enblend-enfuse-4.2/0000755000175000017500000000000012676432767011276 500000000000000enblend-enfuse-4.2/m4/0000755000175000017500000000000012676432767011616 500000000000000enblend-enfuse-4.2/m4/_ac_latex_test.m40000644000175000017500000000241212542526740014740 00000000000000# # Copyright (C) 2004 Boretti Mathieu # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # Internal macro to test a latex file # AC_DEFUN([_AC_LATEX_TEST],[ AC_REQUIRE([AC_PROG_LATEX]) rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ifelse($#,2,[ $2="no"; export $2; cat > testconf.tex << \EOF $1 EOF ],$#,3,[ echo "\\documentclass{$3}" > testconf.tex cat >> testconf.tex << \EOF $1 EOF ],$#,4,[ echo "\\documentclass{$3}" > testconf.tex echo "\\usepackage{$4}" > testconf.tex cat >> testconf.tex << \EOF $1 ]) cat testconf.tex | $latex 2>&1 1>/dev/null && $2=yes; export $2; cd .. rm -rf .tmps_latex ]) enblend-enfuse-4.2/m4/ax_boost_base.m40000644000175000017500000002475412322441231014572 00000000000000# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_boost_base.html # =========================================================================== # # SYNOPSIS # # AX_BOOST_BASE([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # DESCRIPTION # # Test for the Boost C++ libraries of a particular version (or newer) # # If no path to the installed boost library is given the macro searchs # under /usr, /usr/local, /opt and /opt/local and evaluates the # $BOOST_ROOT environment variable. Further documentation is available at # . # # This macro calls: # # AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS) # # And sets: # # HAVE_BOOST # # LICENSE # # Copyright (c) 2008 Thomas Porschberg # Copyright (c) 2009 Peter Adolphs # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 23 AC_DEFUN([AX_BOOST_BASE], [ AC_ARG_WITH([boost], [AS_HELP_STRING([--with-boost@<:@=ARG@:>@], [use Boost library from a standard location (ARG=yes), from the specified location (ARG=), or disable it (ARG=no) @<:@ARG=yes@:>@ ])], [ if test "$withval" = "no"; then want_boost="no" elif test "$withval" = "yes"; then want_boost="yes" ac_boost_path="" else want_boost="yes" ac_boost_path="$withval" fi ], [want_boost="yes"]) AC_ARG_WITH([boost-libdir], AS_HELP_STRING([--with-boost-libdir=LIB_DIR], [Force given directory for boost libraries. Note that this will override library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]), [ if test -d "$withval" then ac_boost_lib_path="$withval" else AC_MSG_ERROR(--with-boost-libdir expected directory name) fi ], [ac_boost_lib_path=""] ) if test "x$want_boost" = "xyes"; then boost_lib_version_req=ifelse([$1], ,1.20.0,$1) boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'` boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` if test "x$boost_lib_version_req_sub_minor" = "x" ; then boost_lib_version_req_sub_minor="0" fi WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req) succeeded=no dnl On 64-bit systems check for system libraries in both lib64 and lib. dnl The former is specified by FHS, but e.g. Debian does not adhere to dnl this (as it rises problems for generic multi-arch support). dnl The last entry in the list is chosen by default when no libraries dnl are found, e.g. when only header-only libraries are installed! libsubdirs="lib" ax_arch=`uname -m` case $ax_arch in x86_64|ppc64|s390x|sparc64|aarch64) libsubdirs="lib64 lib lib64" ;; esac dnl allow for real multi-arch paths e.g. /usr/lib/x86_64-linux-gnu. Give dnl them priority over the other paths since, if libs are found there, they dnl are almost assuredly the ones desired. AC_REQUIRE([AC_CANONICAL_HOST]) libsubdirs="lib/${host_cpu}-${host_os} $libsubdirs" case ${host_cpu} in i?86) libsubdirs="lib/i386-${host_os} $libsubdirs" ;; esac dnl first we check the system location for boost libraries dnl this location ist chosen if boost libraries are installed with the --layout=system option dnl or if you install boost with RPM if test "$ac_boost_path" != ""; then BOOST_CPPFLAGS="-I$ac_boost_path/include" for ac_boost_path_tmp in $libsubdirs; do if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp" break fi done elif test "$cross_compiling" != yes; then for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then for libsubdir in $libsubdirs ; do if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir" BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" break; fi done fi dnl overwrite ld flags if we have required special directory with dnl --with-boost-libdir parameter if test "$ac_boost_lib_path" != ""; then BOOST_LDFLAGS="-L$ac_boost_lib_path" fi CPPFLAGS_SAVED="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" export CPPFLAGS LDFLAGS_SAVED="$LDFLAGS" LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" export LDFLAGS AC_REQUIRE([AC_PROG_CXX]) AC_LANG_PUSH(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @%:@include ]], [[ #if BOOST_VERSION >= $WANT_BOOST_VERSION // Everything is okay #else # error Boost version is too old #endif ]])],[ AC_MSG_RESULT(yes) succeeded=yes found_system=yes ],[ ]) AC_LANG_POP([C++]) dnl if we found no boost with system layout we search for boost libraries dnl built and installed without the --layout=system option or for a staged(not installed) version if test "x$succeeded" != "xyes"; then _version=0 if test "$ac_boost_path" != ""; then if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` V_CHECK=`expr $_version_tmp \> $_version` if test "$V_CHECK" = "1" ; then _version=$_version_tmp fi VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" done fi else if test "$cross_compiling" != yes; then for ac_boost_path in /usr /usr/local /opt /opt/local ; do if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` V_CHECK=`expr $_version_tmp \> $_version` if test "$V_CHECK" = "1" ; then _version=$_version_tmp best_path=$ac_boost_path fi done fi done VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" if test "$ac_boost_lib_path" = ""; then for libsubdir in $libsubdirs ; do if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done BOOST_LDFLAGS="-L$best_path/$libsubdir" fi fi if test "x$BOOST_ROOT" != "x"; then for libsubdir in $libsubdirs ; do if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'` stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'` V_CHECK=`expr $stage_version_shorten \>\= $_version` if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT) BOOST_CPPFLAGS="-I$BOOST_ROOT" BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir" fi fi fi fi CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" export CPPFLAGS LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" export LDFLAGS AC_LANG_PUSH(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @%:@include ]], [[ #if BOOST_VERSION >= $WANT_BOOST_VERSION // Everything is okay #else # error Boost version is too old #endif ]])],[ AC_MSG_RESULT(yes) succeeded=yes found_system=yes ],[ ]) AC_LANG_POP([C++]) fi if test "$succeeded" != "yes" ; then if test "$_version" = "0" ; then AC_MSG_NOTICE([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation.]]) else AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) fi # execute ACTION-IF-NOT-FOUND (if present): ifelse([$3], , :, [$3]) else AC_SUBST(BOOST_CPPFLAGS) AC_SUBST(BOOST_LDFLAGS) AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available]) # execute ACTION-IF-FOUND (if present): ifelse([$2], , :, [$2]) fi CPPFLAGS="$CPPFLAGS_SAVED" LDFLAGS="$LDFLAGS_SAVED" fi ]) enblend-enfuse-4.2/m4/lrint.m40000644000175000017500000000171012070530376013106 00000000000000dnl @synopsis AC_C99_FUNC_LRINT dnl dnl Check whether C99's lrint function is available. dnl @version 1.1 dnl @author Erik de Castro Lopo dnl dnl Permission to use, copy, modify, distribute, and sell this file for any dnl purpose is hereby granted without fee, provided that the above copyright dnl and this permission notice appear in all copies. No representations are dnl made about the suitability of this software for any purpose. It is dnl provided "as is" without express or implied warranty. dnl AC_DEFUN([AC_C99_FUNC_LRINT], [AC_CACHE_CHECK(for lrint, ac_cv_c99_lrint, [AC_TRY_COMPILE([ #define _ISOC9X_SOURCE 1 #define _ISOC99_SOURCE 1 #define __USE_ISOC99 1 #define __USE_ISOC9X 1 #include ], [ int value = lrint (0.432) ; ], ac_cv_c99_lrint=yes, ac_cv_c99_lrint=no)]) if test $ac_cv_c99_lrint = yes; then AC_DEFINE(HAVE_LRINT, 1, [Define if you have C99's lrint function.]) fi ])# AC_C99_LRINT enblend-enfuse-4.2/m4/ax_with_prog.m40000644000175000017500000000460312070530376014454 00000000000000# =========================================================================== # http://www.nongnu.org/autoconf-archive/ax_with_prog.html # =========================================================================== # # SYNOPSIS # # AX_WITH_PROG([VARIABLE],[program],[VALUE-IF-NOT-FOUND],[PATH]) # # DESCRIPTION # # Locates an installed program binary, placing the result in the precious # variable VARIABLE. Accepts a present VARIABLE, then --with-program, and # failing that searches for program in the given path (which defaults to # the system path). If program is found, VARIABLE is set to the full path # of the binary; if it is not found VARIABLE is set to VALUE-IF-NOT-FOUND # if provided, unchanged otherwise. # # A typical example could be the following one: # # AX_WITH_PROG(PERL,perl) # # NOTE: This macro is based upon the original AX_WITH_PYTHON macro from # Dustin J. Mitchell . # # LICENSE # # Copyright (c) 2008 Francesco Salvestrini # Copyright (c) 2008 Dustin J. Mitchell # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. AC_DEFUN([AX_WITH_PROG],[ AC_PREREQ([2.61]) pushdef([VARIABLE],$1) pushdef([EXECUTABLE],$2) pushdef([VALUE_IF_NOT_FOUND],$3) pushdef([PATH_PROG],$4) AC_ARG_VAR(VARIABLE,Absolute path to EXECUTABLE executable) AS_IF(test -z "$VARIABLE",[ AC_MSG_CHECKING(whether EXECUTABLE executable path has been provided) AC_ARG_WITH(EXECUTABLE,AS_HELP_STRING([--with-EXECUTABLE=[[[PATH]]]],absolute path to EXECUTABLE executable), [ AS_IF([test "$withval" != yes -a "$withval" != no],[ VARIABLE="$withval" AC_MSG_RESULT($VARIABLE) ],[ VARIABLE="" AC_MSG_RESULT([no]) AS_IF([test "$withval" != no], [ AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[]) ]) ]) ],[ AC_MSG_RESULT([no]) AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[]) ]) ]) popdef([PATH_PROG]) popdef([VALUE_IF_NOT_FOUND]) popdef([EXECUTABLE]) popdef([VARIABLE]) ]) enblend-enfuse-4.2/m4/ac_latex_package.m40000644000175000017500000000443012542526740015217 00000000000000# # Copyright (C) 2004 Boretti Mathieu # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # AC_LATEX_PACKAGE([],,) # # Test the presences of package and set $ # to yes or no # # dnl @synopsis AC_LATEX_PACKAGE(,,) dnl dnl This macro test if package in exists dnl and set to the right value dnl dnl AC_LATEX_PACKAGE(varioref,book,vbook) dnl should set $vbook="yes" dnl dnl AC_LATEX_PACKAGE(xyz,book,vbook) dnl should set $vbook="no" dnl dnl @version 1.3 dnl @author Mathieu Boretti boretti@eig.unige.ch dnl AC_DEFUN([AC_LATEX_PACKAGE],[ if test "$[ac_cv_latex_class_]translit($2,[-],[_])" = "" ; then AC_LATEX_CLASS($2,boretti_classesansparametre) export boretti_classesansparametre; else boretti_classesansparametre=$[ac_cv_latex_class_]translit($2,[-],[_]) ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then AC_MSG_ERROR([Unable to find $2 class]) fi AC_CACHE_CHECK([for $1 in class $2],[ac_cv_latex_]translit($1,[-],[_])[_]translit($2,[-],[_]),[ _AC_LATEX_TEST([ \documentclass{$2} \usepackage{$1} \begin{document} \end{document} ],[ac_cv_latex_]translit($1,[-],[_])[_]translit($2,[-],[_])) ]) $3=$[ac_cv_latex_]translit($1,[-],[_])[_]translit($2,[-],[_]); export $3; AC_SUBST($3) ifelse($#,3,[],$#,4,[ if test "[$]$3" = "yes" ; then $4 fi ],$#,5,[ ifelse($4,[],[ if test "[$]$3" = "no" ; then $5 fi ],[ if test "[$]$3" = "yes" ; then $4 else $5 fi ]) ]) ]) enblend-enfuse-4.2/m4/lrintf.m40000644000175000017500000000172412070530376013261 00000000000000dnl @synopsis AC_C99_FUNC_LRINTF dnl dnl Check whether C99's lrintf function is available. dnl @version 1.1 dnl @author Erik de Castro Lopo dnl dnl Permission to use, copy, modify, distribute, and sell this file for any dnl purpose is hereby granted without fee, provided that the above copyright dnl and this permission notice appear in all copies. No representations are dnl made about the suitability of this software for any purpose. It is dnl provided "as is" without express or implied warranty. dnl AC_DEFUN([AC_C99_FUNC_LRINTF], [AC_CACHE_CHECK(for lrintf, ac_cv_c99_lrintf, [AC_TRY_COMPILE([ #define _ISOC9X_SOURCE 1 #define _ISOC99_SOURCE 1 #define __USE_ISOC99 1 #define __USE_ISOC9X 1 #include ], [ int value = lrintf (0.432) ; ], ac_cv_c99_lrintf=yes, ac_cv_c99_lrintf=no)]) if test $ac_cv_c99_lrintf = yes; then AC_DEFINE(HAVE_LRINTF, 1, [Define if you have C99's lrintf function.]) fi ])# AC_C99_LRINTF enblend-enfuse-4.2/m4/ac_type_sig_atomic_t.m40000644000175000017500000000111512253101765016121 00000000000000AC_DEFUN([AC_TYPE_SIG_ATOMIC_T], [AC_MSG_CHECKING(for sig_atomic_t) AC_CACHE_VAL(ac_cv_type_sig_atomic_t, AC_TRY_COMPILE([#include ], [sig_atomic_t foo = 1;], ac_cv_type_sig_atomic_t=yes, ac_cv_type_sig_atomic_t=no)) if test "$ac_cv_type_sig_atomic_t" = no; then AC_DEFINE(sig_atomic_t, int, [largest atomically accessible type]) fi AC_MSG_RESULT($ac_cv_type_sig_atomic_t)]) enblend-enfuse-4.2/m4/ax_cxx_compile_stdcxx_11.m40000644000175000017500000001040512253101765016656 00000000000000# SYNOPSIS # # AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) # # DESCRIPTION # # Check for baseline language coverage in the compiler for the C++11 # standard; if necessary, add switches to CXXFLAGS to enable support. # # The first argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. # -std=c++11). If neither is specified, you get whatever works, with # preference for an extended mode. # # The second argument, if specified 'mandatory' or if left unspecified, # indicates that baseline C++11 support is required and that the macro # should error out if no mode with that support is found. If specified # 'optional', then configuration proceeds regardless, after defining # HAVE_CXX11 if and only if a supporting mode is found. # # LICENSE # # Copyright (c) 2008 Benjamin Kosnik # Copyright (c) 2012 Zack Weinberg # Copyright (c) 2013 Roy Stogner # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 3 m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [ template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; typedef check> right_angle_brackets; int a; decltype(a) b; typedef check check_type; check_type c; check_type&& cr = static_cast(c); auto d = a; ]) AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl m4_if([$1], [], [], [$1], [ext], [], [$1], [noext], [], [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl m4_if([$2], [], [ax_cxx_compile_cxx11_required=true], [$2], [mandatory], [ax_cxx_compile_cxx11_required=true], [$2], [optional], [ax_cxx_compile_cxx11_required=false], [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl AC_LANG_PUSH([C++])dnl ac_success=no AC_CACHE_CHECK(whether $CXX supports C++11 features by default, ax_cv_cxx_compile_cxx11, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], [ax_cv_cxx_compile_cxx11=yes], [ax_cv_cxx_compile_cxx11=no])]) if test x$ax_cv_cxx_compile_cxx11 = xyes; then ac_success=yes fi m4_if([$1], [noext], [], [dnl if test x$ac_success = xno; then for switch in -std=gnu++11 -std=gnu++0x; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, $cachevar, [ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], [eval $cachevar=yes], [eval $cachevar=no]) CXXFLAGS="$ac_save_CXXFLAGS"]) if eval test x\$$cachevar = xyes; then CXXFLAGS="$CXXFLAGS $switch" ac_success=yes break fi done fi]) m4_if([$1], [ext], [], [dnl if test x$ac_success = xno; then for switch in -std=c++11 -std=c++0x; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, $cachevar, [ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], [eval $cachevar=yes], [eval $cachevar=no]) CXXFLAGS="$ac_save_CXXFLAGS"]) if eval test x\$$cachevar = xyes; then CXXFLAGS="$CXXFLAGS $switch" ac_success=yes break fi done fi]) AC_LANG_POP([C++]) if test x$ax_cxx_compile_cxx11_required = xtrue; then if test x$ac_success = xno; then AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) fi else if test x$ac_success = xno; then HAVE_CXX11=0 AC_MSG_NOTICE([No compiler with C++11 support was found]) else HAVE_CXX11=1 AC_DEFINE(HAVE_CXX11,1, [define if the compiler supports basic C++11 syntax]) fi AC_SUBST(HAVE_CXX11) fi ]) enblend-enfuse-4.2/m4/ax_openmp.m40000644000175000017500000001027312070530376013750 00000000000000# =========================================================================== # http://www.nongnu.org/autoconf-archive/ax_openmp.html # =========================================================================== # # SYNOPSIS # # AX_OPENMP([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro tries to find out how to compile programs that use OpenMP a # standard API and set of compiler directives for parallel programming # (see http://www-unix.mcs/) # # On success, it sets the OPENMP_CFLAGS/OPENMP_CXXFLAGS/OPENMP_F77FLAGS # output variable to the flag (e.g. -omp) used both to compile *and* link # OpenMP programs in the current language. # # NOTE: You are assumed to not only compile your program with these flags, # but also link it with them as well. # # If you want to compile everything with OpenMP, you should set: # # CFLAGS="$CFLAGS $OPENMP_CFLAGS" # #OR# CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" # #OR# FFLAGS="$FFLAGS $OPENMP_FFLAGS" # # (depending on the selected language). # # The user can override the default choice by setting the corresponding # environment variable (e.g. OPENMP_CFLAGS). # # ACTION-IF-FOUND is a list of shell commands to run if an OpenMP flag is # found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it is # not found. If ACTION-IF-FOUND is not specified, the default action will # define HAVE_OPENMP. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # # 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 3 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, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. AC_DEFUN([AX_OPENMP], [ AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX AC_CACHE_CHECK([for OpenMP flag of _AC_LANG compiler], ax_cv_[]_AC_LANG_ABBREV[]_openmp, [save[]_AC_LANG_PREFIX[]FLAGS=$[]_AC_LANG_PREFIX[]FLAGS ax_cv_[]_AC_LANG_ABBREV[]_openmp=unknown # Flags to try: -fopenmp (gcc), -openmp (icc), -mp (SGI & PGI), # -xopenmp (Sun), -omp (Tru64), -qsmp=omp (AIX), none ax_openmp_flags="-fopenmp -openmp -mp -xopenmp -omp -qsmp=omp none" if test "x$OPENMP_[]_AC_LANG_PREFIX[]FLAGS" != x; then ax_openmp_flags="$OPENMP_[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flags" fi for ax_openmp_flag in $ax_openmp_flags; do case $ax_openmp_flag in none) []_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[] ;; *) []_AC_LANG_PREFIX[]FLAGS="$save[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flag" ;; esac AC_TRY_LINK_FUNC(omp_set_num_threads, [ax_cv_[]_AC_LANG_ABBREV[]_openmp=$ax_openmp_flag; break]) done []_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[]FLAGS ]) if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" = "xunknown"; then m4_default([$2],:) else if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" != "xnone"; then OPENMP_[]_AC_LANG_PREFIX[]FLAGS=$ax_cv_[]_AC_LANG_ABBREV[]_openmp fi m4_default([$1], [AC_DEFINE(HAVE_OPENMP,1,[Define if OpenMP is enabled])]) fi ])dnl AX_OPENMP enblend-enfuse-4.2/m4/ac_latex_class.m40000644000175000017500000000335012542526740014731 00000000000000# # Copyright (C) 2004 Boretti Mathieu # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # AC_LATEX_CLASS(,) # # Test the presences of class and set $ # to yes or no # # dnl @synopsis AC_LATEX_CLASSE(,) dnl dnl Test if class1 exists dnl and set $var to the right value dnl dnl AC_LATEX_CLASSES([book],book) dnl should set $book="yes" dnl dnl AC_LATEX_CLASSES(allo,book) dnl should set $book="no" dnl dnl @version 1.3 dnl @author Mathieu Boretti boretti@eig.unige.ch dnl AC_DEFUN([AC_LATEX_CLASS],[ AC_CACHE_CHECK([for class $1],[ac_cv_latex_class_]translit($1,[-],[_]),[ _AC_LATEX_TEST([ \begin{document} \end{document} ],[ac_cv_latex_class_]translit($1,[-],[_]),$1) ]) $2=$[ac_cv_latex_class_]translit($1,[-],[_]) ; export $2; AC_SUBST($2) ifelse($#,2,[],$#,3,[ if test "[$]$2" = "yes" ; then $3 fi ],$#,4,[ ifelse($3,[],[ if test "[$]$2" = "no" ; then $4 fi ],[ if test "[$]$2" = "yes" ; then $3 else $4 fi ]) ]) ]) enblend-enfuse-4.2/m4/ax_cxx_as_const.m40000644000175000017500000000207512623317170015145 00000000000000# SYNOPSIS # # AX_CXX_AS_CONST # # DESCRIPTION # # If the C++ compiler supports std::as_const(), define HAVE_AS_CONST. # # LICENSE # # Copyright (c) 2015 Christoph L. Spiel # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 1 AU_ALIAS([AC_CXX_AS_CONST], [AX_CXX_AS_CONST]) AC_DEFUN([AX_CXX_AS_CONST], [dnl AC_CACHE_CHECK([whether the compiler supports as_const()], ax_cv_cxx_as_const, [dnl AC_LANG_PUSH([C++]) AC_COMPILE_IFELSE([dnl AC_LANG_PROGRAM(dnl [ #include #include #include ], [std::string s("foo"); const std::string& const_s = std::as_const(s)])], ax_cv_cxx_as_const=yes, ax_cv_cxx_as_const=no) AC_LANG_POP([C++]) ]) AS_IF([test "X$ax_cv_cxx_as_const" = Xyes], [AC_DEFINE(HAVE_AS_CONST,,[define if the compiler supports as_const()])]) ]) enblend-enfuse-4.2/m4/ac_prog_latex.m40000644000175000017500000000237412542526740014600 00000000000000# # Copyright (C) 2004 Boretti Mathieu # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # AC_PROG_LATEX # # Test for latex or elatax or lambda # and set $latex to the correct value. # # dnl @synopsis AC_PROG_LATEX dnl dnl This macro test if latex is installed. If latex dnl is installed, it set $latex to the right value dnl dnl @version 1.3 dnl @author Mathieu Boretti boretti@eig.unige.ch dnl AC_DEFUN([AC_PROG_LATEX],[ AC_CHECK_PROGS(latex,[latex elatex lambda],no) export latex; if test $latex = "no" ; then AC_MSG_ERROR([Unable to find a LaTeX application]); fi AC_SUBST(latex) ]) enblend-enfuse-4.2/m4/ac_prog_ar.m40000644000175000017500000000026712253077572014067 00000000000000m4_ifndef([AC_PROG_AR], [AN_MAKEVAR([AR], [AC_PROG_AR]) AN_PROGRAM([ar], [AC_PROG_AR]) AC_DEFUN([AC_PROG_AR], [AC_CHECK_TOOL(AR, ar, :)]) ]) enblend-enfuse-4.2/m4/ax_prog_perl_modules.m40000644000175000017500000000420712070530376016173 00000000000000# =========================================================================== # http://www.nongnu.org/autoconf-archive/ax_prog_perl_modules.html # =========================================================================== # # SYNOPSIS # # AX_PROG_PERL_MODULES([MODULES], [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # # DESCRIPTION # # Checks to see if the given perl modules are available. If true the shell # commands in ACTION-IF-TRUE are executed. If not the shell commands in # ACTION-IF-FALSE are run. Note if $PERL is not set (for example by # calling AC_CHECK_PROG, or AC_PATH_PROG), AC_CHECK_PROG(PERL, perl, perl) # will be run. # # MODULES is a space separated list of module names. To check for a # minimum version of a module, append the version number to the # module name, separated by an equals sign. # # Example: # # AX_PROG_PERL_MODULES( Text::Wrap Net::LDAP=1.0.3, , # AC_MSG_WARN(Need some Perl modules) # # LICENSE # # Copyright (c) 2009 Dean Povey # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. AU_ALIAS([AC_PROG_PERL_MODULES], [AX_PROG_PERL_MODULES]) AC_DEFUN([AX_PROG_PERL_MODULES],[dnl m4_define([ax_perl_modules]) m4_foreach([ax_perl_module], m4_split(m4_normalize([$1])), [ m4_append([ax_perl_modules], [']m4_bpatsubst(ax_perl_module,=,[ ])[' ]) ]) # Make sure we have perl if test -z "$PERL"; then AC_CHECK_PROG(PERL,perl,perl) fi if test "x$PERL" != x; then ax_perl_modules_failed=0 for ax_perl_module in ax_perl_modules; do AC_MSG_CHECKING(for perl module $ax_perl_module) # Would be nice to log result here, but can't rely on autoconf internals $PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1 if test $? -ne 0; then AC_MSG_RESULT(no); ax_perl_modules_failed=1 else AC_MSG_RESULT(ok); fi done # Run optional shell commands if test "$ax_perl_modules_failed" = 0; then : $2 else : $3 fi else AC_MSG_WARN(could not find perl) fi])dnl enblend-enfuse-4.2/doc/0000755000175000017500000000000012676432767012043 500000000000000enblend-enfuse-4.2/doc/common-interaction.tex0000644000175000017500000006046012676423754016314 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Interacting with \App\commonpart]{\label{sec:interaction}% \genidx[\rangebeginlocation]{interaction with \App}% Interacting with \App\commonpart} This section explains how to find out about the inner workings of \emph{your} version of \App{} without looking at the source code. And it states how to interact with \App{} besides passing command-line options and image filenames. \subsection[Finding Out Details]{\label{sec:finding-out-details}% \genidx{detailed configuration}% Finding Out Details About \app} An \appcmd{} binary can come in several configurations. The exact name of the binary may vary and it may or may not reflect the ``kind of \app''. Therefore, \appcmd{} offers several options that allow the user to query exactly\dots \begin{compactitemize} \item what its exact version number is (see \sectionabbr~\fullref{sec:exact-version} and option~\flexipageref{\option{--ver\shyp sion}}{opt:version}), \item what features it does support (see \sectionabbr~\fullref{sec:compiled-in-features} and options~\flexipageref{\option{--ver\shyp sion}}{opt:version} and \flexipageref{\option{--ver\shyp bose}}{opt:verbose}), \item which image formats it can read and write without the need of conversion (see \sectionabbr~\fullref{sec:image-formats} and option~\flexipageref{\option{--show-image-for\shyp mats}}{opt:show-image-formats}), \item who built it, (see \sectionabbr~\fullref{sec:name-of-builder} and option~\flexipageref{\option{--show-signature}}{opt:show-signature}), and finally \item what compiler and libraries were used to do so (see \sectionabbr~\fullref{sec:compiler-and-libraries} and option~\flexipageref{\option{--show-soft\shyp ware-com\shyp po\shyp nents}}{opt:show-software-components}). \end{compactitemize} The information are explained in detail in the following sections. \subsubsection[Exact Version]{\label{sec:exact-version}% \genidx{version!software}% \gensee{software version}{version, software}% \genidx{version!query}% \gensee{query version}{version, query}% \optidx{--version}% Exact Version Number} \exampleName~\ref{ex:option-version} shows a possible output of \sample{\app{} --version}. The version number at the beginning of the text tells about the \emph{exact} version of the binary. It is the number that can be compared with the version number of this document, which by the way is \val{val:VERSION}. Our slightly cranky markup (see also \flexipageref{Notation}{sec:notation}) dispels copy-paste errors. \begin{exemplar} \begin{terminal} \$ \app{} --version \\ \app{} 4.2-02c1f45857b4 \\ ~ \\ Copyright (C) 2004-2009 Andrew Mihal. \\ Copyright (C) 2009-2015 Christoph Spiel. \\ ~ \\ License GPLv2+: GNU GPL version 2 or later \\ This is free software: you are free to change and redistribute it. \\ There is NO WARRANTY, to the extent permitted by law. \\ ~ \\ Written by Andrew Mihal, Christoph Spiel and others. \end{terminal} \caption[Output of \sample{\app{} --version}]% {\label{ex:option-version}% Example output of \appcmd{} when called with option~\option*{--version}.} \end{exemplar} \genidx{branches of \App\slash\OtherApp!development}% \gensee{development branch}{branches, development}% \gensee{development branch}{branches, development}% The version indicator consist of a two (major and minor version) or three (major and minor version plus patch-level) numbers separated by dots and an optional hexadecimal identifier. Binaries from the ``Development Branch'' are assigned two-part version numbers, whereas a three-part version number is reserved for the ``Stable Branch'' of development. Officially released versions lack the hexadecimal identifier. \noindent Examples: \begin{codelist} \item[4.1.3-0a816672d475]\itemend Some unreleased version from the ``Stable Branch'', which finally will lead to version~4.1.3. \item[4.1.3]\itemend Officially released version~4.1.3 in the ``Stable Branch''. \item[4.2-1e4d237daabf]\itemend Some unreleased version from the ``Development Branch'', which finally will lead to version~4.2. \item[4.2]\itemend Officially released version~4.2 in the ``Development Branch''. \end{codelist} Matching the version codes is the only reliably way to pair a given binary with its manual page (``manual page for enblend~4.2-1e4d237daabf'') and its documentation. This document mentions the version code for example on its \ifhevea Title \else Title Page \fi and the \flexipageref{Abstract}{sec:abstract}. \genidx{public repository}% \gensee{source code repository}{public repository}% \gensee{code repository}{public repository}% The twelve-digit hexadecimal \metavar{ID-CODE} is automatically generated by our source-code versioning system, \appidx{Mercurial}\uref{\mercurialseleniccom}{Mercurial}. Use the \metavar{ID-CODE} to look up the version on the web in our \uref{\enblendhgcodesfnet}{public source code repository} or, if you have cloned the project to your own workspace, with the command \begin{literal} hg log --verbose --rev \metavar{ID-CODE} \end{literal} \subsubsection[Compiled-In Features]{\label{sec:compiled-in-features}% \genidx{features}% \genidx{query!features}% \gensee{compiled-in features}{features}% \gensee{extra features}{features}% \optidx{--version}% \optidx{--verbose}% Compiled-In Features} Adding option~\option{--verbose} to~\option{--version} will reproduce the information described in the previous section plus a list of ``extra features''. Any unavailable feature in the particular binary queried returns \begin{literal} Extra feature: \dots: no \end{literal} whereas available features answer ``\code{yes}'' followed by a detailed report on the feature and its connection to some library or specific hardware. \exampleName~\fullref{ex:option-version-verbose} shows such a report. Remember that your binary may include more or less of the features displayed there. \begin{exemplar} \begin{maxipage} \begin{terminal} \$ \app{} --version --verbose \\ \app{} 4.2-95f1fed2bf2d \\ ~ \\ Extra feature: dynamic linking support: yes \\ Extra feature: image cache: no \\ Extra feature: OpenMP: no \\ ~ \\ Copyright (C) 2004-2009 Andrew Mihal. \\ Copyright (C) 2009-2015 Christoph Spiel. \\ ~ \\ License GPLv2+:~GNU GPL version 2 or later \\ This is free software: you are free to change and redistribute it. \\ There is NO WARRANTY, to the extent permitted by law. \\ ~ \\ Written by Andrew Mihal, Christoph Spiel and others. \end{terminal} \end{maxipage} \caption[Output of \sample{\app{} --version --verbose}]% {\label{ex:option-version-verbose}% Example output of \appcmd{} when called with options \option*{--version} and~\option*{--verbose} together.} \end{exemplar} The \sample{--version --verbose}~combo is one of the first things test if \appcmd{} ``suddenly'' behaves strangely. \begin{qandalist} \item ``I'm running my \appcmd{} on a multi-core system, but it does not make use of it.'' \begin{qandaanswer} Check for extra feature \acronym{OpenMP}. \end{qandaanswer} \item ``My \appcmd{} complains when I call it with \sample{--gpu}!'' \begin{qandaanswer} Check for extra feature \acronym{OpenCL}. \end{qandaanswer} \item ``\appcmd{} is so slow!'' \begin{qandaanswer} Ensure that \emph{neither} feature \code{mmap-view} \emph{nor} \code{image-cache} has been compiled in. \end{qandaanswer} \item ``\appcmd{} eats away too much memory! Can I tell it to unload that onto the disk?'' \begin{qandaanswer} No, there is no command-line switch for that, but you can use a version with \code{mmap-view}~feature. \end{qandaanswer} \item ``My \appcmd{} has \acronym{OpenMP} enabled. Does it support dynamic adjustment of the number of threads?'' \begin{qandaanswer} Under extra feature \acronym{OpenMP} look for ``support for dynamic adjustment of the number of threads''. \end{qandaanswer} %% -- Commented out for Stable Branch 4.2 %% \item %% ``My \appcmd{} has \acronym{OpenCL} enabled. Does it need separate \acronym{OpenCL} source %% files?'' %% \begin{qandaanswer} %% Under extra feature \acronym{OpenCL} look for ``Search path''. If there is none, all %% sources have been included in the binary, otherwise the \acronym{OpenCL} source files %% should be put somewhere on the \acronym{OpenCL} search path. %% \end{qandaanswer} \end{qandalist} \subsubsection[Image Formats]{\label{sec:image-formats}% \genidx{image formats}% \genidx{query!image formats}% \optidx{--show-image-formats}% Supported Images Formats} \App{} can read and write a fixed set of image formats if it was compiled to support them. For example the \acronym{EXR}-format requires special support libraries. Use option~\option{--show-image-formats} to find out \begin{compactitemize} \item what image-data formats are supported, \item what filename extensions are recognized, and \item what per-channel depths have been compiled into the \appcmd{} binary. \end{compactitemize} \noindent The only three image formats always supported are \begin{compactitemize} \genidx{image formats!JPEG@\acronym{JPEG}}% \item \acronym{JPEG}, \genidx{image formats!PNG@\acronym{PNG}}% \item \acronym{PNG}, and \genidx{image formats!TIFF@\acronym{TIFF}}% \item \acronym{TIFF}. \end{compactitemize} \genidx{image formats!OpenEXR@\acronym{OpenEXR}}% \noindent All others are optional. In particular the high-dynamic range (\acronym{HDR}) format \acronym{OpenEXR} only gets compiled if several non-standard libraries are available. The provided per-channel depths range from just one, namely ``8~bits unsigned integral'' (\code{uint8}) up to seven: \begin{compactitemize} \item 8~bits unsigned integral, \sample{uint8} \item 16~bits unsigned or signed integral, \sample{uint16} or \sample{int16} \item 32~bits unsigned or signed integral, \sample{uint32} or \sample{int32} \item 32~bits floating-point, \sample{float} \item 64~bits floating-point, \sample{double} \end{compactitemize} \tableName~\ref{tab:image-format-and-bit-depth} summarizes the channel bit depths of some prominent image formats. %% With the exception of TIFF, VIFF, PNG, and PNM all file types %% store only 1 byte (gray scale and mapped RGB) or 3 bytes (RGB) %% per pixel. %% %% PNG can store UInt8 and UInt16 values, and supports 1 and 3 %% channel images. One additional alpha channel is also supported. %% %% PNM can store 1 and 3 channel images with UInt8, UInt16 and %% UInt32 values in each channel. %% %% TIFF and VIFF are additionally able to store short and long %% integers (2 or 4 bytes) and real values (32 bit float and 64 bit %% double) without conversion. \begin{table} \genidx{image formats}% \genidx{bits per channel}% \gensee{bit depth}{bits per channel}% \genidx{channel!alpha}% \genidx{profile!ICC@\acronym{ICC}}% \gensee{ICC profile@\acronym{ICC} profile}{profile, \acronym{ICC}}% \def\avail{$\bullet$}% \def\unava{$-$}% \def\unkwn{?}% \ifreferencemanual\begin{maxipage}\fi \centering \begin{tabular}{l cc ccccc} \hline \multicolumn{1}{c|}{} & \multicolumn{1}{c|}{} & \multicolumn{1}{c|}{} & \multicolumn{5}{c}{Channel Bit-Depth} \\ \cline{4-8} \multicolumn{1}{c|}{Format} & \multicolumn{1}{c|}{Mask} & \multicolumn{1}{c|}{Profile} & \multicolumn{3}{c|}{Integral} & \multicolumn{2}{c}{Floating-Point} \\ \cline{4-8} \multicolumn{1}{c|}{} & \multicolumn{1}{c|}{} & \multicolumn{1}{c|}{} & \multicolumn{1}{c|}{\code{uint8}} & \multicolumn{1}{c|}{\code{uint16}} & \multicolumn{1}{c|}{\code{uint32}} & \multicolumn{1}{c|}{\code{float}} & \multicolumn{1}{c}{\code{double}} \\ \hline\extraheadingsep \acronym{JPEG} & \unava & \avail & \avail & \unava & \unava & \unava & \unava \\ \acronym{PNG} & \avail & \avail & \avail & \avail & \unava & \unava & \unava \\ \acronym{PNM} & \unkwn & \unava & \avail & \avail & \avail & \unava & \unava \\ \optional{\acronym{V}}\acronym{TIFF} & \avail & \avail & \avail & \avail & \avail & \avail & \avail \end{tabular} \ifreferencemanual\end{maxipage}\fi \caption[Image formats and bit-depths]% {\label{tab:image-format-and-bit-depth}% Bit-depths of selected image formats. These are the maximum capabilities of the formats themselves, not \App's. The ``Mask''-column indicates whether the format supports an image mask (alpha-channel), see also \chapterName~\ref{sec:understanding-masks}. Column~``Profile'' shows whether the image format allows for \acronym{ICC}-profiles to be included; see also \chapterName~\ref{sec:color-spaces}.} \end{table} \subsubsection[Builder]{\label{sec:name-of-builder}% \genidx{name of builder}% \genidx{builder}% \genidx{query!name of builder}% \genidx{signature}% \gensee{signed binary}{signature}% \optidx{--show-signature}% Name Of Builder} During building each \appcmd{} is automatically signed to give the users an extra level of confidence that it was constructed by someone that they can trust to get it right. Access this signature with \sample{--show-signature} and \appcmd{} will print something like \begin{literal} Compiled on sgctrl03 by Walter Harriman on Wed, Dec 22 2004, 16:07:22 GMT-7. \end{literal} \noindent where machine name, person, and date-time depend on the build. \subsubsection[Compiler And Libraries]{\label{sec:compiler-and-libraries}% \genidx{compiler}% \genidx{libraries}% \genidx{query!compiler}% \genidx{query!libraries}% \optidx{--show-software-components}% Compiler And Libraries Used To Build} Sometimes \appcmd{} refuses to start or runs into trouble because the libraries supplied to it do not match the ones it was compiled with. Option~\option{--show\hyp soft\shyp ware\hyp components} can be helpful to diagnose the problem in such cases, because it shows the version information of \App's most important libraries as they have identified themselves during compile-time. \genidx{OpenMP@\acronym{OpenMP}}% Furthermore the report reveals the compiler used to build \appcmd{} along with the most important compiler extensions like, for example, \acronym{OpenMP}. \exampleName~\ref{ex:show-software-components} shows such a report. \begin{exemplar} \begin{terminal} \$ \app{} --show-software-components \\ Compiler \\ ~~g++ 4.9.1 \\ ~~implementing OpenMP standard of 2013-7 \\ ~~implementing Cilk version 2.0 \\ ~~~~without support of "\_Cilk\_for" keyword \\ ~ \\ Libraries \\ ~~GSL:~~~~~~~~1.15 \\ ~~Little CMS:~2.7.0 \\ ~~Vigra:~~~~~~1.10.0 \end{terminal} \caption[Output of \sample{\app{} --show-software-components}]% {\label{ex:show-software-components}% Output of \appcmd{} when asked to reveal the compiler that was used to build it along with the libraries it was linked against.} \end{exemplar} \subsection[Console Messages]{\label{sec:console-messages}% \genidx{console messages}% \genidx{message!console}% Console Messages} \App{} is meant to read multiple images, ``montage'' them together, and finally write a single output image. So, any console messages either serve the entertainment desire of the user or indicate problems. \genidx{message!category}% When \appcmd{} is instructed to only show information about its configuration (see \sectionName~\fullref{sec:information-options}) the text goes to Standard~Output. \appcmd{} sends error and warning messages to Standard~Error. The messages follow a fixed format. \begin{literal} \app: \optional{\metavar{CATEGORY}:} \metavar{MESSAGE} \end{literal} \noindent where \metavar{CATEGORY} is \begin{codelist} \genidx{message!category!error}% \item[error:] A serious problem that sooner or later will lead to a program stop. The result will definitely not be what the user wants -- including no output image at all, as \appcmd{} deletes corrupted or incomplete output images. Most messages drop category name~\sample{error} and plainly write \metavar{MESSAGE}: \begin{literal} enblend: input image "1.tif" does not have an alpha channel \end{literal} \genidx{return code}% \gensea{code}{return code}% If an \sample{error} actually leads to a premature termination of \appcmd, it returns code~1 to the operating system. On successful termination the return code is 0. \genidx{message!category!warning}% \item[warning:] A problem that forces \appcmd{} to take an alternate execution path or drop some assumptions about the input. \genidx{message!category!info}% \item[info:] No problem, just a ``nice-to-know'' information for the user. \genidx{message!category!note}% \item[note:] Not a standalone \metavar{CATEGORY}, but an additional explanation that sometimes trails messages in one of the above categories. Errors, warnings and infos tell the causes, notes inform about the actions taken by \appcmd{}. Here is an example, where a \code{warning} gets augmented by a \code{note}: \begin{literal} enblend: warning: input images too small for coarse mask \\ enblend: note: switching to fine mask \end{literal} \genidx{message!category!timing}% \item[timing:] A measurement of the execution duration and thus a sub\hyp{}category of \code{info}. \end{codelist} \noindent Sadly, not all messages can be sorted in the category scheme. \begin{description} \genidx{message!debug}% \item[Debug Messages:] Though debug messages generally come devoid of a specific form the more civilized of them start each line with a plus sign~\sample{+}. Example: \begin{literal} + checkpoint: leaving channel width alone \end{literal} \genidx{message!foreign sources}% \item[Foreign Sources:] \appcmd{} depends on various foreign software components that issue their own messages. We try to catch them and press them in our category scheme, but some of them invariably slip through. The most prominent members of this rogue fraction are the notices of \uref{\hciiwrvigra}{\acronym{VIGRA}} as e.g. \begin{literal} enfuse: an exception occurred \\ enfuse: Precondition violation! \\ \dots \end{literal} and \uref{\remotesensingorglibtiff}{LibTIFF}: \begin{literal} TIFFReadDirectory: Warning, img0001.tif: wrong data type 1 for "RichTIFFIPTC"; tag ignored. \end{literal} \genidx{message!should-never-happen@``should never happen''}% \item[``Should-Never-Happen'':] An internal consistency check fails or a cautious routine detects a problem with its parameters and racks up the digital equivalent of a nervous breakdown. Sometimes these messages end in the word~\sample{Aborted}. \begin{literal} terminate called after throwing an instance of '\dots' \\ what(): \dots \\ Aborted \end{literal} If the installation of \appcmd{} is correct, this type of message may warrant a bug report as explained in \appendixName~\fullref{sec:bug-reports}. \end{description} In very unfortunate circumstances \App{} quits because of a problem, but does not show any message. The output file then either does not exist or it is broken. One known reason are out-of-memory situations, where the process needs additional memory, but cannot allocate it and while terminating needs even more memory so that the operating system wipes it out completely wherever it then happens to be in its execution path. \subsection[Environment Variables]{\label{sec:environment-variables}% \genidx{environment variable}% \gensee{variable}{environment variable}% \gensea{environment}{environment variable}% Environment Variables} A small set of environment variables influences the execution of \appcmd. All of them depend on \appcmd{} having been compiled with certain features. The hint ``(direct)'' indicates genuine variables in \appcmd, whereas ``(implicit)'' denotes variables that control libraries that are linked with \appcmd. \begin{description} \genidx[\summarylocation]{environment variable} \newcommand*{\xitemspace}{\ifhevea~~\else\hspace{.667em}\fi} \renewcommand{\makelabel}[1]{\hspace{\labelsep}#1} \genidx{environment variable!CILK\_NWORKERS@\envvar{CILK\_NWORKERS}}% \gensee{CILK\_NWORKERS@\envvar{CILK\_NWORKERS}}{environment variable, \envvar{CILK\_NWORKERS}}% \item[\envvar{CILK\_NWORKERS}\xitemspace (implicit)\xitemspace \restrictednote{\acronym{Cilk}-enabled versions only.}]\itemend This environment variable works for \uref{\cilkplusorg}{CilkPlus} as \envvar{OMP\_NUM\_THREADS} (see below) does for \acronym{OpenMP}. It can be helpful for load balancing. %% -- Commented out for Stable Branch 4.2 %% \genidx{environment variable!ENBLEND\_OPENCL\_PATH@\envvar{ENBLEND\_OPENCL\_PATH}}% %% \gensee{ENBLEND\_OPENCL\_PATH@\envvar{ENBLEND\_OPENCL\_PATH}}% %% {environment variable, \envvar{ENBLEND\_OPENCL\_PATH}}% %% \genidx{OpenCL@\acronym{OpenCL}}% %% \item[\envvar{ENBLEND\_OPENCL\_PATH}\xitemspace (direct)\xitemspace %% \restrictednote{\acronym{OpenCL}-enabled versions only.}]\itemend %% Search path for \uref{\khronosorgopencl}{\acronym{OpenCL}} (\filename{.cl}) source files. %% \appcmd{} will refuse to run if required \acronym{OpenCL}~source files are missing, but can be %% convinced to start by resigning \acronym{OpenCL} with \sample{--no-gpu}. If the compiled-in %% features (see \sectionName~\fullref{sec:compiled-in-features}) do not show an \acronym{OpenCL} %% search path, \appcmd{} came with internalized \acronym{OpenCL} sources and neither needs nor %% uses \envvar{ENBLEND\_OPENCL\_PATH}. %% %% \ifenfuse %% \restrictednote{\application{Enfuse} only.} \command{enfuse} uses the environment variable %% \envvar{ENBLEND\_OPENCL\_PATH} as search path for User-Defined \acronym{OpenCL} Exposure %% Weighting Functions. See \sectionName~\fullref{sec:user-defined-opencl-functions}. %% \fi %% %% Note that the environment variable is called \envvar{ENBLEND\_OPENCL\_PATH} for \emph{both} %% applications, even for \command{enfuse}! \genidx{environment variable!OMP\_DYNAMIC@\envvar{OMP\_DYNAMIC}}% \gensee{OMP\_DYNAMIC@\envvar{OMP\_DYNAMIC}}{environment variable, \envvar{OMP\_DYNAMIC}}% \genidx{OpenMP@\acronym{OpenMP}}% \item[\envvar{OMP\_DYNAMIC}\xitemspace (implicit)\xitemspace \restrictednote{\acronym{OpenMP}-enabled versions only.}]\itemend Control whether the \uref{\openmporg}{\acronym{OpenMP}} sub-system should parallelize nested parallel regions. This environment variable will only have an effect is the \acronym{OpenMP} sub-system is capable of dynamic adjustment of the number of threads (see explanations in \sectionName~\fullref{sec:compiled-in-features}). \begin{geeknote} \noindent The important hot spots in the source code override the value of \envvar{OMP\_DYNAMIC}. \end{geeknote} \genidx{environment variable!OMP\_NUM\_THREADS@\envvar{OMP\_NUM\_THREADS}}% \gensee{OMP\_NUM\_THREADS@\envvar{OMP\_NUM\_THREADS}}% {environment variable, \envvar{OMP\_NUM\_THREADS}}% \genidx{OpenMP@\acronym{OpenMP}}% \item[\envvar{OMP\_NUM\_THREADS}\xitemspace (implicit)\xitemspace \restrictednote{\acronym{OpenMP}-enabled versions only.}]\itemend Control -- which typically means: reduce -- the number of threads under supervision of the \uref{\openmporg}{\acronym{OpenMP}} sub-system. By default \appcmd{} uses as many \acronym{OpenMP}\hyp{}threads as there are \acronym{CPU}s. Use this variable for example to free some \acronym{CPU}s for other processes than \appcmd. \genidx{environment variable!TMPDIR@\envvar{TMPDIR}}% \gensee{TMPDIR@\envvar{TMPDIR}}{environment variable, \envvar{TMPDIR}}% \item[\envvar{TMPDIR}\xitemspace (direct)\xitemspace \restrictednote{\sample{mmap\_view}-branch only.}]\itemend \envvar{TMPDIR} determines the directory and thus the drive where \appcmd{} stores all intermediate images. The best choice follows the same rules as for a swap-drive: prefer the fastest disk with the least load. \end{description} %% \subsection[External Files]{External Files %% \label{sec:external-files} %% \genidx{external files} %% \genidx{files!external}} \genidx[\rangeendlocation]{interaction with \App} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enfuse-local-entropy-weighting.tex0000644000175000017500000000642012667245423020534 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Local Entropy Weighting]{\label{sec:local-entropy-weighting}% \genidx[\rangebeginlocation]{local entropy weighting}% \genidx{weighting!local entropy}% \gensee{entropy}{weighting, local entropy}% \gensee{local entropy}{weighting, local entropy}% Local Entropy Weighting} Entropy weighting prefers pixels inside a high entropy neighborhood. \genidx{entropy!definition}Let $S$ be an $n$-ary source. Watching the output of $S$ an observer on average gains the information \[ H_a(n) := \sum_{x \in S} p(x) \log_a(1 / p(x)) \] \noindent per emitted message, where we assume the knowledge of the probability function~$p(S)$. The expectation value~$H_a(n)$ is called entropy of the source~$S$. Entropy measures our uncertainty if we are to guess which message gets chosen by the source in the future. The unit of the entropy depends on the choice of the constant~$a > 1$. Obviously \[ H_b(n) = H_a(n) / \log_a(b) \] \noindent holds for all $b > 1$. We use $a = 2$ for entropy weighting and set the entropy of the ``impossible message'' to zero according to \[ \lim_{p \rightarrow 0} \, p \, \log_a(1 / p) = 0. \] \figureName~\ref{fig:entropy} shows an entropy function. \begin{figure} \ifreferencemanual\begin{maxipage}\fi \centering \includeimage{entropy} \ifreferencemanual\end{maxipage}\fi \caption[Entropy function]{\label{fig:entropy}% Entropy function~$H_2(p)$ for an experiment with exactly two outcomes.} \end{figure} For more on (information) entropy visit \uref{\wikipediainformationentropy}{Wikipedia}. \genidx{weighting!local entropy!window size}% \App{} computes a pixel's entropy by considering the pixel itself and its surrounding pixels quite similar to Local-Contrast Weighting (\fullref{sec:local-contrast-weighting}). The size of the window is set by \sample{--entropy-window-size}. Choosing the right size is difficult, because there is a serious tradeoff between the locality of the data and the size of the sample used to compute $H$. A large window results in a large sample size and therefore in a reliable entropy, but considering pixels far away from the center degrades $H$ into a non-local measure. For small windows the opposite holds true. Another difficulty arises from the use of entropy as a weighting function in dark parts of an image, that is, in areas where the signal-to-noise ratio is low. Without any precautions, high noise is taken to be high entropy, which might not be desired. Use option~\option{--entropy-cutoff} to control the black level when computing the entropy. On the other extreme side of lightness, very light parts of an image, the sensor might already have overflown without the signal reaching 1.0 in the normalized luminance interval. For these pixels the entropy is zero and \App{} can be told of the threshold by properly setting the second argument of \sample{--entropy-cutoff}. \begin{optionsummary} \item[--entropy-cutoff] \sectionName~\fullref{opt:entropy-cutoff} \item[--entropy-weight] \sectionName~\fullref{opt:entropy-weight} \item[--entropy-window-size] \sectionName~\fullref{opt:entropy-window-size} \end{optionsummary} \genidx[\rangeendlocation]{local entropy weighting} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/smooth-edge.gp0000644000175000017500000000033412566032753014513 00000000000000# Plot an example of a smooth edge set contour set grid set hidden3d set style data line set view 60, 30 set xtics 0, 1, 4 set ytics 0, 1, 4 unset key splot DATA_DIR . "/smooth-edge.data" matrix title "smooth edge" enblend-enfuse-4.2/doc/external-mask-workflow.dot0000644000175000017500000000137112562317012017073 00000000000000digraph ExternalMaskWorkflow { graph [uml_activity_graph] node [uml_activity] _start [uml_start] generate [label = "Generate Masks"] modify [label = "Modify Masks"] use [label = "Blend or Fuse\nUsing Masks"] _finish [uml_finish] node [uml_note] generate_note [label = "Enblend, Enfuse --save-masks"] modify_note [label = "Any image editor"] use_note [label = "Enblend, Enfuse --load-masks"] {rank = same; generate; generate_note} {rank = same; modify; modify_note} {rank = same; use; use_note} edge [uml_edge] _start -> generate generate -> modify modify -> use use -> _finish edge [uml_note_edge] generate -> generate_note modify -> modify_note use -> use_note } enblend-enfuse-4.2/doc/common-response-files.tex0000644000175000017500000002775012676175561016740 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Response Files\commonpart]{\label{sec:response-files}% \genidx[\rangebeginlocation]{response files}% \genidx{file!response}% Response Files\commonpart} A response file contains names of images or other response filenames. \genidx{\val*{val:response-file-prefix-char}\ (response file prefix)}% \gensee{response file prefix!\sample{\val*{val:response-file-prefix-char}}}% {\sample{\val*{val:response-file-prefix-char}}} Introduce response file names at the command line or in a response file with an \code{\val{val:response-file-prefix-char}}~character. \genidx{order!of image processing}% \gensee{image processing order}{order of image processing}% \App{} and \OtherApp{} process the list \metavar{INPUT} strictly from left to right, expanding response files in depth-first order. Multi-layer files are processed from first layer to the last. The following examples only show \application{Enblend}, but \application{Enfuse} works exactly the same. \begin{description} \item[Solely image filenames.]\itemend Example: \begin{literal} enblend image-1.tif image-2.tif image-3.tif \end{literal} The ultimate order in which the images are processed is: \filename{image-1.tif}, \filename{image-2.tif}, \filename{image-3.tif}. \item[Single response file.]\itemend Example: \begin{literal} enblend \val*{val:response-file-prefix-char} list \end{literal} where file~\filename{list} contains \begin{literal} img1.exr \\ img2.exr \\ img3.exr \\ img4.exr \\ \end{literal} Ultimate order: \filename{img1.exr}, \filename{img2.exr}, \filename{img3.exr}, \filename{img4.exr}. \item[Mixed literal names and response files.]\itemend Example: \begin{literal} enblend \val*{val:response-file-prefix-char} master.list image-09.png image-10.png \end{literal} where file~\filename{master.list} comprises of \begin{literal} image-01.png \\ \val*{val:response-file-prefix-char} first.list \\ image-04.png \\ \val*{val:response-file-prefix-char} second.list \\ image-08.png \\ \end{literal} \filename{first.list} is \begin{literal} image-02.png \\ image-03.png \\ \end{literal} and \filename{second.list} contains \begin{literal} image-05.png \\ image-06.png \\ image-07.png \\ \end{literal} Ultimate order: \filename{image-01.png}, \filename{image-02.png}, \filename{image-03.png}, \filename{image-04.png}, \filename{image-05.png}, \filename{image-06.png}, \filename{image-07.png}, \filename{image-08.png}, \filename{image-09.png}, \filename{image-10.png}, \end{description} \subsection[Response File Format]{\label{sec:response-file-format}% \genidx{response file!format}% \gensee{format of response file}{response file format}% Response File Format} \genidx{\val*{val:response-file-comment-char} (response file comment)}% \gensee{response file!comment (\sample{\val*{val:response-file-comment-char}})}% {\sample{\val*{val:response-file-comment-char}}}% Response files contain one filename per line. Blank lines or lines beginning with a \code{\val{val:response-file-comment-char}}~sign are ignored; the latter can serve as comments. Filenames that begin with a \code{\val{val:response-file-prefix-char}}~character denote other response files. \tableName~\ref{tab:response-file-format} states a formal grammar of response files in \uref{\wikipediaebnf}{\acronym{EBNF}}. \begin{table} \begin{tabular}{l@{$\quad::=\quad$}l} \metavar{response-file} & \metavar{line}* \\ \metavar{line} & (\metavar{comment} $|$ \metavar{file-spec}) [\sample{\bslash r}] \sample{\bslash n} \\ \metavar{comment} & \metavar{space}* \sample{\val*{val:response-file-comment-char}} \metavar{text} \\ \metavar{file-spec} & \metavar{space}* \sample{\val*{val:response-file-prefix-char} } \metavar{filename} \metavar{space}* \\ \metavar{space} & \sample{\textvisiblespace} $|$ \sample{\bslash t} \\ \end{tabular} \noindent where \metavar{text} is an arbitrary string and \metavar{filename} is any filename. \caption[Grammar of response files]{\label{tab:response-file-format}% \genidx{response file!grammar}% \gensee{grammar!response file}{response file, grammar}% \acronym{EBNF} definition of the grammar of response files.} \end{table} In a response file relative filenames are used relative the response file itself, not relative to the current-working directory of the application. The above grammar might surprise the user in the some ways. \begin{description} \item[White-space trimmed at both line ends]\itemend For convenience, white-space at the beginning and at the end of each line is ignored. However, this implies that response files cannot represent filenames that start or end with white-space, as there is no quoting syntax. Filenames with embedded white-space cause no problems, though. \item[Only whole-line comments]\itemend Comments in response files always occupy a complete line. There are no ``line-ending comments''. Thus, in \begin{literal} \val*{val:response-file-comment-char} exposure series \\ img-0.33ev.tif \val*{val:response-file-comment-char} "middle" EV \\ img-1.33ev.tif \\ img+0.67ev.tif \\ \end{literal} only the first line contains a comment, whereas the second line includes none. Rather, it refers to a file called \begin{literal} img-0.33ev.tif \val*{val:response-file-comment-char} "middle" EV \end{literal} \item[Image filenames cannot start with \code{\val{val:response-file-prefix-char}}]\itemend A \code{\val{val:response-file-prefix-char}}~sign invariably introduces a response file, even if the filename's extension hints towards an image. \end{description} \genidx{response file!force recognition of}% If \App{} or \OtherApp{} do not recognize a response file, they will skip the file and issue a warning. To force a file being recognized as a response file add one of the following syntactic comments to the \emph{first} line of the file. \begin{literal} response-file: true\synidx{response-file} \\ enblend-response-file: true\synidx{enblend-response-file} \\ enfuse-response-file: true\synidx{enfuse-response-file} \\ \end{literal} Finally, \exampleName~\ref{ex:response-file} shows a complete response file. \begin{exemplar} \begin{literal} \val*{val:response-file-comment-char}~4\bslash pi panorama! \\ \mbox{} \\ \val*{val:response-file-comment-char}~These pictures were taken with the panorama head. \\ \val*{val:response-file-prefix-char}~round-shots.list \\ \mbox{} \\ \val*{val:response-file-comment-char}~Freehand sky shot. \\ zenith.tif \\ \mbox{} \\ \val*{val:response-file-comment-char}~"Legs, will you go away?" images. \\ nadir-2.tif \\ nadir-5.tif \\ nadir.tif \\ \end{literal} \caption[Complete response file]% {\label{ex:response-file}% Example of a complete response file.} \end{exemplar} \subsection[Syntactic Comments]{\label{sec:syntactic-comments}% \genidx{response file!syntactic comment}% \gensee{syntactic comment!response file}{response file, syntactic comment}% Syntactic Comments} Comments that follow the format described in \tableName~\ref{tab:response-file-syntactic-comment} are treated as instructions how to interpret the rest of the response file. A syntactic comment is effective immediately and its effect persists to the end of the response file, unless another syntactic comment undoes it. \begin{table} \begin{tabular}{l@{$\quad::=\quad$}l} \metavar{syntactic-comment} & \metavar{space}* \sample{\val*{val:response-file-comment-char}} \metavar{space}* \metavar{key} \metavar{space}* \sample{:} \metavar{space}* \metavar{value} \\ \metavar{key} & (\sample{A}\dots \sample{Z} $|$ \sample{a}\dots \sample{z} $|$ \sample{-})+ \\ \end{tabular} where \metavar{value} is an arbitrary string. \caption[Grammar of syntactic comments]{\label{tab:response-file-syntactic-comment}% \genidx{syntactic comment!grammar}% \genidx{grammar!syntactic comment}% \acronym{EBNF} definition of the grammar of syntactic comments in response files.} \end{table} Unknown syntactic comments are silently ignored. A special index for \flexipageref{syntactic comments}{sec:syncomm-index} lists them in alphabetic order. \subsection[Globbing Algorithms]{\label{sec:globbing-algorithms}% \genidx{globbing algorithm}% \gensee{algorithm}{globbing algorithm}% Globbing Algorithms} The three equivalent syntactic keys \begin{compactitemize} \item \code{glob},\synidx{glob} \item \code{globbing},\synidx{globbing} or \item \code{filename-globbing}\synidx{filename-globbing} \end{compactitemize} \noindent control the algorithm that \App{} or \OtherApp{} use to glob filenames in response files. \genidx{globbing algorithm!\code{literal}}% \genidx{globbing algorithm!\code{wildcard}}% All versions of \App{} and \OtherApp{} support at least two algorithms: \code{literal}, which is the default, and \code{wildcard}. See \tableName~\ref{tab:globbing-algorithms} for a list of all possible globbing algorithms. To find out about the algorithms in your version of \App{} or \OtherApp{} use option~\option{--show-globbing-algorithms}. \begin{table} \begin{minipage}{\linewidth} \begin{codelist} \genidx{globbing algorithm!\code{literal}}% \item[literal]\itemend Do not glob. Interpret all filenames in response files as literals. This is the default. Please remember that white-space at both ends of a line in a response file \emph{always} gets discarded. \genidx{globbing algorithm!\code{wildcard}}% \genidx{glob}% \item[wildcard]\itemend Glob using the wildcard characters~\sample{?}, \sample{*}, \sample{[}, and \sample{]}. The \propername{Win32} implementation only globs the filename part of a path, whereas all other implementations perform wildcard expansion in \emph{all} path components. Also see \uref{\kernelorgglob}{\manpage{glob}{7}}. \genidx{globbing algorithm!\code{none}} \item[none]\itemend Alias for \code{literal}. \genidx{globbing algorithm!\code{shell}} \item[shell]\itemend The \code{shell} globbing algorithm works as \code{literal} does. In addition, it interprets the wildcard characters~\sample{\{}, \sample{\atsign}, and \sample{\squiggle}. This makes the expansion process behave more like common \acronym{UN*X} shells. \genidx{globbing algorithm!\code{sh}} \item[sh]\itemend Alias for \code{shell}. \end{codelist} \end{minipage} \caption[Globbing algorithms]{\label{tab:globbing-algorithms}% \genidx{globbing algorithms}% \genidx{algorithms!globbing}% Globbing algorithms for the use in response files.} \end{table} \exampleName~\ref{ex:globbing-algorithm} gives an example of how to control filename-globbing in a response file. \begin{exemplar} \begin{literal} \val*{val:response-file-comment-char}~Horizontal panorama \\ \val*{val:response-file-comment-char}~15 images \\ \mbox{} \\ \val*{val:response-file-comment-char}~filename-globbing: wildcard \\ \mbox{} \\ image\_000[0-9].tif \\ image\_001[0-4].tif \\ \end{literal} \caption[Filename-globbing syntactic comment]% {\label{ex:globbing-algorithm}% Control filename-globbing in a response file with a syntactic comment.} \end{exemplar} \subsection[Default Layer Selection]{\label{sec:default-layer-selection}% \genidx{default layer selection}% \genidx{layer selection!default}% Default Layer Selection} The key~\code{layer-selector}\synidx{layer-selector} provides the same functionality as does the command\hyp{}line option~\option{--layer-selector}, but on a per response\hyp{}file basis. See \sectionName~\ref{sec:common-options}. This syntactic comment affects the layer selection of all images listed after it including those in included response files until another \code{layer-selector} overrides it. \genidx[\rangeendlocation]{response files} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/focus-stack-decision-tree.dot0000644000175000017500000000372112562317012017423 00000000000000digraph FocusStackDecisionTree { graph [uml_activity_graph, uml_compressed_layout] node [uml_activity] _start [uml_start] local_contrast_window [label = "Use local contrast window"] if_visible_seams_branch [uml_branch] laplacian_of_gaussian [label = "Use Laplacian-of-Gaussian"] if_still_visible_branch [uml_branch] if_still_visible_merge [uml_merge] positive_min_curvature [label = "Apply positive MinCurvature"] if_loss_branch [uml_branch] if_loss_merge [uml_merge] local_contrast_enhancement [label = "Use local contrast\nenhancement"] if_mild_loss_branch [uml_branch] negative_min_curvature [label = "Apply negative MinCurvature"] if_mild_loss_merge [uml_merge] _finish [uml_finish] {rank = same; if_still_visible_branch; if_still_visible_merge} {rank = same; if_loss_branch; if_loss_merge} edge [uml_edge] _start -> local_contrast_window local_contrast_window -> if_visible_seams_branch if_visible_seams_branch -> laplacian_of_gaussian [taillabel = " [visible seams] ", weight = 10] if_visible_seams_branch -> if_still_visible_merge [taillabel = " [else] "] laplacian_of_gaussian -> if_still_visible_branch if_still_visible_branch -> if_still_visible_merge [taillabel = " [else] " ] if_still_visible_merge -> if_loss_merge if_still_visible_branch -> positive_min_curvature [taillabel = " [still visible seams] ", weight = 10] positive_min_curvature -> if_loss_branch if_loss_branch -> if_mild_loss_branch [taillabel = " [loss of detail] ", weight = 10] if_loss_branch -> if_loss_merge [taillabel = " [else] "] if_loss_merge -> _finish if_mild_loss_branch -> local_contrast_enhancement [taillabel = " [mild loss of detail] ", weight = 10] local_contrast_enhancement -> if_mild_loss_merge if_mild_loss_branch -> if_mild_loss_merge [taillabel = " [else] "] if_mild_loss_merge -> negative_min_curvature negative_min_curvature -> _finish [weight = 10] } enblend-enfuse-4.2/doc/common-standard-workflow.tex0000644000175000017500000000752212676175561017445 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Standard Workflow]{\label{sec:standard-workflow}% \genidx{workflow!standard}% \gensee{standard workflow}{workflow, standard}% Standard, All-In-One Workflow} \figureName~\ref{fig:photographic-workflow} shows where \App{} and \OtherApp{} sit in the tool chain of the standard workflow. \begin{figure} \begin{maxipage} \centering \includeimage{photographic-workflow} \end{maxipage} \caption[Photographic workflow]{\label{fig:photographic-workflow}% \genidx{workflow!\application{Enblend}}% \genidx{workflow!\application{Enfuse}}% \prgidx{dcraw}% \prgidx{ufraw}% \appidx{Hugin}% \appidx{PanoTools}% \appidx{Gimp}% Photographic workflow with \App{} and \OtherApp.} \end{figure} \begin{description} \item[Take Images]\itemend Take \emph{multiple} images to form a panorama, an exposure series, a focus stack, etc.\dots There is one exception with \application{Enfuse} when a single raw image is converted multiple times to get several -- typically differently ``exposed'' -- images. \noindent\emph{Exemplary Benefits:} \begin{itemize} \item Many pictures taken from the same vantage point but showing different viewing directions. -- Panorama \item Pictures of the same subject exposed with different shutter speeds. -- Exposure series \item Images of the same subject focused at differing distances. -- Focus stack \end{itemize} \noindent\emph{Remaining Problem:} The ``overlayed'' images may not fit together, that is the overlay regions may not match exactly. \genidx{conversion!raw}% \gensee{raw conversion}{conversion, raw}% \item[Convert Images]\itemend Convert the \uref{\luminouslandscaperawfiles}{raw data} exploiting the full dynamic range of the camera and capitalize on a high-quality conversion. \item[Align Images]\itemend Align the images so as to make them match as well as possible. Again there is one exception and this is when images naturally align. For example, a series of images taken from a rock solid tripod with a cable release without touching the camera, or images taken with a shift lens, can align without further user intervention. \genidx{transformation!affine}% \gensee{affine transformation}{transformation, affine}% This step submits the images to affine transformations. \genidx{lens distortion!correction of}% If necessary, it rectifies the lens' distortions (e.g.\ barrel or pincushion), too. \genidx{alignment!photometric}% \gensee{photometric alignment}{alignment, photometric}% Sometimes even luminance or color differences between pairs of overlaying images are corrected (``photometric alignment''). \noindent\emph{Benefit:} The overlay areas of images match as closely as possible given the quality if the input images and the lens model used in the transformation. \genidx{parallax error}% \noindent\emph{Remaining Problem:} The images may still not align perfectly, for example, because of \uref{\wikipediaparallax}{parallax} errors, or blur produced by camera shake. \item[Combine Images]\itemend \App{} and \OtherApp{} combine the aligned images into one. \noindent\emph{Benefit:} The overlay areas become imperceptible for all but the most misaligned images. \genidx{channel!alpha}% \noindent\emph{Remaining Problem:} Enblend and Enfuse write images with an alpha channel; for more information on alpha channels see \chapterName~\fullref{sec:understanding-masks}. Furthermore, the final image rarely is rectangular. \item[Post-process]\itemend Post-process the combined image with your favorite tool. Often the user will want to crop the image and simultaneously throw away the alpha channel. \item[View] \item[Print] \item[Enjoy] \end{description} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/colors.gp0000644000175000017500000000130512541464343013575 00000000000000# new originally set linetype 1 linecolor rgbcolor "#ff3366" # orangered red set linetype 2 linecolor rgbcolor "#2eb800" # forestgreen green set linetype 3 linecolor rgbcolor "#3366ff" # navyblue blue set linetype 4 linecolor rgbcolor "#ff33cc" # rhodamine magenta set linetype 5 linecolor rgbcolor "#33ffcc" # seagreen cyan set linetype 6 linecolor rgbcolor "#b800f5" # orchid brown set linetype 7 linecolor rgbcolor "#ccff33" # springgreen dark-yellow set linetype 8 linecolor rgbcolor "#ffcc33" # dandelion orange set linetype 9 linecolor rgbcolor "#ff6633" # brickred red set linetype cycle 9 enblend-enfuse-4.2/doc/enfuse-exposure-weighting.tex0000644000175000017500000002604212676423754017625 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Exposure Weighting]{\label{sec:exposure-weighting}% \genidx{weighting!exposure}% \gensee{exposure weighting}{weighting, exposure}% Exposure Weighting} \optidx{--exposure-optimum}% Exposure weighting prefers pixels with a luminance~$Y$ close to the user-chosen optimum value (option~\option{--exposure-optimum}, default: \val{val:default-exposure-optimum}) of the normalized, real-valued luminance interval~$(0, 1)$. \genidx{projector!grayscale}% \gensee{grayscale projector}{projector, grayscale}% \optidx{--gray-projector}% \acronym{RGB}-pixels get converted to luminance before using the grayscale projector given by \sample{--gray-projector}, which defaults to \code{average}. Grayscale pixels simply are identified with luminance. \genidx{luminance interval!normalized}% \gensee{normalized luminance interval}{luminance interval, normalized}% In the normalized luminance interval 0.0 represents pure black and 1.0 represents pure white independently of the data type of the input image. This is, for a \acronym{JPEG} image the luminance~255 maps to 1.0 in the normalized interval and for a 32~bit \acronym{TIFF} picture the highest luminance value~4294967295 also maps to 1.0. The middle of the luminance interval, 0.5, is where a neutral gray tone ends up with every camera that had no exposure correction dialed in, for example the image of any gray-card or white-card. The exposure weighting algorithm only looks at a single pixel at a time; the pixel's neighborhood is not taken into account. \subsection[Built-In Functions]{\label{sec:built-in-functions}% \genidx{weighting!exposure!built-in}% Built-In Functions} \genidx{exposure weight function!\code{gauss}}% \genidx{exposure weight function!\propername{Gaussian}}% Up to \App{} version~4.1 the only weighting function is the \propername{Gaussian} \begin{equation*}\refrep{equ:weight:gauss}% w_{\mathrm{exp}}(Y) = \exp\left(-\frac{1}{2} \left( \frac{Y - Y_{\mathrm{opt}}}{\mathit{width}} \right)^2\right), \end{equation*} \noindent whose maximum position~$Y_{\mathrm{opt}}$ and $width$ are controlled by the command line options \option{--exposure-optimum} and~\option{--exposure-width} respectively, where $Y_{\mathrm{opt}}$ defaults to \val{val:default-exposure-optimum} and $width$ defaults to \val{val:default-exposure-width}. \figureName~\ref{fig:gaussian} shows some \propername{Gaussians}. \begin{figure} \ifreferencemanual\begin{maxipage}\fi \centering \includeimage{gaussian} \ifreferencemanual\end{maxipage}\fi \caption[\propername{Gaussian} weight function]{\label{fig:gaussian}% \App{}'s \propername{Gaussian} function with the parameters \metavar{optimum} = 0.5 and three different \metavar{width}s: 0.1, 0.2, and~0.4.} \end{figure} \optidx{--exposure-optimum}% \optidx{--exposure-width}% The options \option{--exposure-optimum} and~\option{--exposure-width} serve to fine-tune the final result without changing the set of input images. Option~\option{--ex\shyp po\shyp sure\hyp op\shyp ti\shyp mum} sets the point of optimum exposure. Increasing the \metavar{optimum} makes \App{} prefer lighter pixels, rendering the final image lighter, and vice versa. Option~\option{--exposure-width} defines the \metavar{width} of acceptable exposures. Small values of \metavar{width} penalize exposures that deviate from \metavar{optimum} more, and vice versa. \optidx{--exposure-weight-function}% In \App{} version~4.2 several new exposure weight functions have been added. Select them with option~\option{--exposure-weight-function}. For the following presentation we refer to the linear luminance transform \begin{equation*}\refrep{equ:linear-luminance-transform} z = \frac{Y - Y_{\mathrm{opt}}}{\mathit{width}}. \end{equation*} as introduced in \equationabbr~\fullref{equ:linear-luminance-transform}. \begin{table} \ifreferencemanual\begin{maxipage}\fi \centering \begin{tabular}{p{.28\textwidth}lcc} \hline \multicolumn{1}{c|}{Exposure Weight} & \multicolumn{1}{c|}{\metavar{WEIGHT-FUNC.}} & \multicolumn{1}{c|}{Equ.} & \multicolumn{1}{c}{Chart} \\ \hline\extraheadingsep \propername{Gaussian} curve (default)% \genidx{exposure weight function!\code{gauss}}% \genidx{exposure weight function!\propername{Gaussian}}% & \code{gauss}, \code{gaussian} & \fullref*{equ:weight:gauss} & \fullref*{fig:gaussian} \\ \propername{Lorentz} curve% \genidx{exposure weight function!\code{lorentz}}% \genidx{exposure weight function!\propername{Lorentz} curve}% \genidx{exposure weight function!\propername{Lorentzian}}% & \code{lorentz}, \code{lorentzian} & \fullref*{equ:weight:lorentz} & \fullref*{fig:lorentzian} \\ Upper half-wave of a sine% \genidx{exposure weight function!\code{halfsine}}% \genidx{exposure weight function!\code{half-sine}}% & \code{halfsine}, \code{half-sine} & \fullref*{equ:weight:halfsine} & \fullref*{fig:halfsine} \\ Full sine-wave shifted upwards by one% \genidx{exposure weight function!\code{fullsine}}% \genidx{exposure weight function!\code{full-sine}}% & \code{fullsine}, \code{full-sine} & \fullref*{equ:weight:fullsine} & \fullref*{fig:fullsine} \\ Quartic, or bi-square function% \genidx{exposure weight function!\code{bisquare}}% \genidx{exposure weight function!\code{bi-square}}% & \code{bisquare}, \code{bi-square} & \fullref*{equ:weight:bisquare} & \fullref*{fig:power} \end{tabular} \ifreferencemanual\end{maxipage}\fi \caption[Exposure weight functions]{\label{tab:weight-functions}% \genidx{exposure weight functions}% Available, compiled-in exposure weight functions.} \end{table} Functions \propername{Gaussian} \begin{equation*}\refrep{equ:weight:gauss}% w_{\mathrm{exp}}(z) = \exp\left(-z^2 / 2\right) \end{equation*} and \propername{Lorentzian} \begin{equation*}\refrep{equ:weight:lorentz} w_{\mathrm{exp}}(z) = \frac{1}{1 + z^2 / 2} \end{equation*} \noindent behave like $1 - z^2$ around the optimum. However for large $|z|$ the \propername{Gaussian} weight rolls off like $\exp(-z^2/2)$ and the \propername{Lorentzian} only as $z^{-2}$. \begin{figure} \ifreferencemanual\begin{maxipage}\fi \centering \includeimage{lorentzian} \ifreferencemanual\end{maxipage}\fi \caption[\propername{Lorentzian} function]{\label{fig:lorentzian}% \App{}'s \propername{Lorentzian} function with the parameters $\metavar{optimum} = 0.5$ and three different \metavar{width}s: 0.1, 0.2, and~0.4.} \end{figure} Both, the \propername{Gaussian} and the \propername{Lorentzian} are easy to use, because they do not go exactly to zero. Thus, \App{} can select ``better'' pixels even far away from the chosen optimum. \begin{figure} \ifreferencemanual\begin{maxipage}\fi \centering \includeimage{halfsine} \ifreferencemanual\end{maxipage}\fi \caption[Half-Sine function]{\label{fig:halfsine}% \App{}'s Half-Sine function with the parameters $\metavar{optimum} = 0.5$ and three different \metavar{width}s: 0.1, 0.2, and~0.4.} \end{figure} \begin{figure} \ifreferencemanual\begin{maxipage}\fi \centering \includeimage{fullsine} \ifreferencemanual\end{maxipage}\fi \caption[Full-Sine function]{\label{fig:fullsine}% \App{}'s Full-Sine function with the parameters $\metavar{optimum} = 0.5$ and three different \metavar{width}s: 0.1, 0.2, and~0.4.} \end{figure} Again, Half-Sine \begin{equation}\refrep{equ:weight:halfsine} w_{\mathrm{exp}}(z) = \left\{\begin{array}{cl} \cos(z) & \mbox{if } |z| \leq \pi/2 \\ 0 & \mbox{otherwise.} \end{array}\right. \end{equation} and Full-Sine \begin{equation}\refrep{equ:weight:fullsine} w_{\mathrm{exp}}(z) = \left\{\begin{array}{cl} (1 + \cos(z)) / 2 & \mbox{if } |z| \leq \pi \\ 0 & \mbox{otherwise.} \end{array} \right. \end{equation} \noindent behave like $1 - z^2$ around the optimum, like \propername{Gaussian} and \propername{Lorentzian}. However for large $|z|$ they both are exactly zero. The difference is how they decrease just before they reach zero. Half-Sine behaves like $z - z'$ and Full-Sine like $(z - z'')^2$, where $z'$ and $z''$ are the respective zeros. \begin{figure} \ifreferencemanual\begin{maxipage}\fi \centering \includeimage{power} \ifreferencemanual\end{maxipage}\fi \caption[Bi-Square function]{\label{fig:power}% \App{}'s Bi-Square function with the parameters $\metavar{optimum} = 0.5$ and three different \metavar{width}s: 0.1, 0.2, and~0.4.} \end{figure} Bi-Square \begin{equation}\refrep{equ:weight:bisquare} w_{\mathrm{exp}}(z) = \left\{ \begin{array}{cl} 1 - z^4 & \mbox{if } |z| \leq 1 \\ 0 & \mbox{otherwise.} \end{array} \right. \end{equation} \noindent is the only predefined function that behaves like $1 - z^4$ around the optimum. The weight functions Half-Sine, Full-Sine, and Bi-Square are more difficult to use, because they yield exactly zero if the normalized luminance of a pixel is far enough away from the optimum. This can lead to pathologies if the luminances of the same pixel position in all $N$ input images are assigned a weight of zero. For all-zero weights \App{} falls back to weighing equally. This is, each pixel gets a weight of $\slfrac{1}{N}$, which may or may not be the desired result. However, if the \metavar{width} is chosen so large that the weight never vanishes or the input images span a large enough range of luminances for each and every pixel, the problem is circumnavigated. \optidx{--exposure-cutoff}% Another way of cutting off underexposed or overexposed pixels is to use option~\option{--exposure-cutoff}, which has the additional benefit of allowing to choose upper and lower cutoff separately. \begin{figure} \ifreferencemanual\begin{maxipage}\fi \centering \includeimage{exposure-weights} \ifreferencemanual\end{maxipage}\fi \caption[Comparison of exposure weight functions]{\label{fig:exposure-weights}% Comparison of all of \App{}'s built-in exposure weight functions~$w(Y)$ for the default values of $\metavar{optimum} = 0.5$ and $\metavar{width} = 0.2$. Note that all functions intersect at $w = \slfrac{1}{2}$, this is, they share the same \acronym{FWHM}.} \end{figure} \figureName~\ref{fig:exposure-weights} compares all available exposure weight functions for the same parameters, namely their defaults. They all intersect at $w = \slfrac{1}{2}$ independently of \metavar{optimum} or \metavar{width}, making it simple to just try them out without fundamentally changing brightness. \subsection[User-Defined Functions]{\label{sec:user-defined-functions}% \genidx{weighting!exposure!user-defined}% User-Defined Exposure Weighting Functions} %% -- Commented out for Stable Branch 4.2 %% Depending on how \App{} was compiled it may support dynamically-linked exposure weighting %% functions, \acronym{OpenCL} exposure weighting functions, or both. \input{enfuse-exposure-weighting-user-dynamic} %% -- Commented out for Stable Branch 4.2 %%\input{enfuse-exposure-weighting-user-opencl} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enblend-overview.tex0000644000175000017500000000635412676175561015764 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Overview]{\label{sec:overview}% \genidx[\rangebeginlocation]{overview}% Overview} \genidx{Burt@\propername{Burt, Peter J.}}% \genidx{Adelson@\propername{Adelson, Edward H.}}% \genidx{Burt-Adelson@\propername{Burt-Adelson}}% \genidx{multi-resolution spline}% \gensee{spline}{multi-resolution spline}% \begin{sloppypar} \App{} overlays multiple images using the \propername{Burt}-\propername{Adelson} multi-resolution spline multi-resolution spline algorithm.\footnotemark{} This technique tries to make the seams between the input images invisible. The basic idea is that image features should be blended across a transition zone proportional in size to the spatial frequency of the features. For example, objects like trees and windowpanes have rapid changes in color. By blending these features in a narrow zone, you will not be able to see the seam because the eye already expects to see color changes at the edge of these features. Clouds and sky are the opposite. These features have to be blended across a wide transition zone because any sudden change in color will be immediately noticeable.% % \footnotetext{\propername{Peter J.~Burt} and \propername{Edward H.~Adelson}, ``A Multiresolution Spline With Application to Image Mosaics'', \acronym{ACM} Transactions on Graphics, \abbreviation{Vol}.~2, \abbreviation{No}.~4, October 1983, pages~217--236.} \end{sloppypar} \genidx{channel!alpha}% \App{} expects each input file to have an alpha channel. The alpha channel should indicate the region of the file that has valid image data. \App{} compares the alpha regions in the input files to find the areas where images overlap. Alpha channels can be used to indicate to \App{} that certain portions of an input image should not contribute to the final image. \genidx{feathering}% \appidx{Hugin}% \appidx{PanoTools}% \App{} does \emph{not} align images. Use a tool such as \application{Hugin} or PanoTools to do this. The \acronym{TIFF}~files produced by these programs are exactly what \App{} is designed to work with. Sometimes these \acronym{GUI}s allow to select feathering for the edges the images. This treatment is detrimental to \App{}. Turn off feathering by deselecting it or setting the ``feather width'' to zero. \App{} blends the images in the order they are specified on the command line. You should order your images according to the way that they overlap, for example from left-to-right across the panorama. If you are making a multi-row panorama, we recommend blending each horizontal row individually, and then running \App{} a last time to blend all of the rows together vertically. The input images are processed in the order they appear on the command line. Multi\hyp{}layer images are processed from the first layer to the last before \App{} considers the next image on the command line. Consult \sectionName~\ref{sec:layer-selection} on how to change the images' order within multi\hyp{}layer image files. \genidx{SourceForge}% Find out more about \App{} on its \uref{\sourceforgenet}{SourceForge} \uref{\enblendsourceforgenet}{web page}. \genidx[\rangeendlocation]{overview} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/updated-on0000755000175000017500000002157512602767761013755 00000000000000#! /usr/bin/env perl # This file is part of Enblend. # Licence details can be found in the file COPYING. # name: updated-on # synopsis: show the date of the most recent update to any of a list of files # author: Dr. Christoph L. Spiel # perl version: 5.20.2 use strict; use warnings; use Carp (); use English; use File::Basename (); use File::stat; use FindBin qw($Bin); use Getopt::Long; use POSIX; use Readonly; use lib $Bin; use Quote (); Readonly my $COMMAND_NAME => File::Basename::basename($PROGRAM_NAME); use constant {DB_NONE => 0, DB_FS => 1, DB_SCM => 2}; sub quote {Quote::gnu_style(@_)} sub quote_list { join(', ', map {quote($_)} @_) } sub gm_time { if ($_[0]) { return gmtime $_[0]; } else { return gmtime; } } sub local_time { if ($_[0]) { return localtime $_[0]; } else { return localtime; } } sub filter_exisiting_files { my @filenames = @_; my @result; foreach my $filename (@filenames) { if (-e $filename) { push @result, $filename; } else { warn "$COMMAND_NAME: warning: file ", quote($filename), " does not exist\n"; } } return @result; } sub filesystem_modification_time { my ($options, $filename) = @_; my $status = stat $filename; my $modification_time = $status->mtime; print STDERR ("$COMMAND_NAME: info: filesystem modification time of ", quote($filename), " is ", POSIX::strftime("%Y-%m-%dT%H%M%S", gmtime($modification_time)), "\n") if $options->{VERBOSE}; return $modification_time; } sub latest_file_modification_time { my ($options, $filenames) = @_; my @modification_times = sort(map {filesystem_modification_time($options, $_)} @$filenames); return (DB_FS, $modification_times[-1]); } sub get_log_date { my $filename = shift; if ($OSNAME eq 'MSWin32') { return qx(hg log --limit 1 --template {date} $filename); } else { return qx(hg log --limit 1 --template '{date}' $filename); } } # hg help templates # hg log --template "{date}\n" ... sub scm_modification_time { my ($options, $filename) = @_; my $log_date = get_log_date($filename); my ($modification_time, $time_zone) = split(m{[+-]}, $log_date); print STDERR ("$COMMAND_NAME: info: SCM modification time of ", quote($filename), " is ", POSIX::strftime("%Y-%m-%dT%H%M%S", gmtime($modification_time)), "\n") if $options->{VERBOSE}; return $modification_time; } sub is_under_scm { my $directory = shift; my $command; if ($OSNAME eq 'MSWin32') { $command = qq(cd $directory & hg root >nul 2>&1); } else { $command = qq(cd '$directory'; hg root > /dev/null 2> /dev/null); } return (system($command) == 0); } sub latest_scm_modification_time { my ($options, $filenames) = @_; my $actual_db = DB_SCM; my %is_under_scm; my @modification_times; foreach my $filename (@$filenames) { my $directory = File::Basename::dirname($filename); if (exists $is_under_scm{$directory} && $is_under_scm{$directory}) { push @modification_times, scm_modification_time($options, $filename); } else { if (is_under_scm($directory)) { print STDERR ("$COMMAND_NAME: info: checking for SCM in directory ", quote($directory), "\n") if $options->{VERBOSE}; push @modification_times, scm_modification_time($options, $filename); $is_under_scm{$directory} = 1; } else { print STDERR ("$COMMAND_NAME: warning: falling back from SCM to file-system for ", quote($filename), "\n"); $actual_db = DB_FS; push @modification_times, filesystem_modification_time($options, $filename); $is_under_scm{$directory} = 0; } } } my @sorted_modification_times = sort(grep {defined $_} @modification_times); if (@sorted_modification_times) { return ($actual_db, $sorted_modification_times[-1]); } else { return (DB_NONE, $options->{DATETIME_FUNCTION}()); } } sub parse_requested_db { my ($a_db_id) = @_; my $db = lc $a_db_id; if ($db eq 'file-system' || $db eq 'fs') { return DB_FS; } elsif ($db eq 'source-code-manager' || $db eq 'scm') { return DB_SCM; } elsif ($db eq 'none' || $db eq 'n/a') { return DB_NONE; } else { warn "$COMMAND_NAME: warning: unknown database id ", quote($a_db_id), "\n"; return DB_NONE; } } my %expansions = (DB_NONE, ['-', 'none'], DB_FS, ['fs', 'file-system'], DB_SCM, ['scm', 'source-code-manager']); sub override_expansion { my ($override_spec) = @_; my ($db_id, $expansions) = split /:/, $override_spec; my ($short_form, $long_form) = split /,/, $expansions; my $db = parse_requested_db($db_id); $short_form ||= $expansions{$db}->[0]; $long_form ||= $expansions{$db}->[1]; $expansions{$db} = [$short_form, $long_form]; } sub expand_db_source { my ($actual_db, $datetime) = @_; $actual_db ||= DB_NONE; Carp::croak("internal error: unknown db") unless exists $expansions{$actual_db}; my $db = $expansions{$actual_db}; $datetime =~ s#%q#$db->[0]#g; $datetime =~ s#%Q#$db->[1]#g; return $datetime; } sub show_help { my $options = shift; print <{DATABASE})]}] to query, where SYSTEM is either @{[quote_list ('source-code-manager', 'scm', 'file-system', 'fs')]} -f, --format=FORMAT strftime(3)-like date FORMAT [@{[quote($options->{DATETIME_FORMAT})]}]; in addition @{[quote('%Q')]} expands to the actual database in long form (file-system, source-code-manager), and @{[quote('%q')]} to the short form @{[quote_list qw(fs scm)]} -G, --gmtime base time on GMT [default] -L, --localtime use local time -O, --override=SPEC override the output of @{[quote_list('%q', '%Q')]}, where SPEC ::= SYSTEM:[SHORT-FORM],[LONG-FORM] is a *single* specification; use multiple times to override multiple specifications -v, --verbose verbosely report progress -h, --help show this help screen Examples: $COMMAND_NAME --format='%Y-%m-%dT%H%M%S' --localtime *.tex $COMMAND_NAME --database=scm --format='%Y-%m-%d\$^{\\textrm{%q}}\$' *.gp END_OF_HELP exit 0; } sub get_options { my $options = shift; Getopt::Long::Configure('no_ignore_case'); Getopt::Long::GetOptions('d|database=s' => \$options->{DATABASE}, 'f|format=s' => \$options->{DATETIME_FORMAT}, 'G|gmtime' => sub {$options->{DATETIME_FUNCTION} = \&gm_time}, 'L|localtime|local-time' => sub {$options->{DATETIME_FUNCTION} = \&local_time}, 'O|override=s' => sub {override_expansion($_[1])}, 'v|verbose' => \$options->{VERBOSE}, 'h|help' => sub {show_help($options)}) or warn "$COMMAND_NAME: problems while parsing options\n"; } sub show_last_update { my ($options, $filenames) = @_; my $db = parse_requested_db($options->{DATABASE}); my $actual_db = DB_NONE; my $latest_time = $options->{DATETIME_FUNCTION}(); if ($db == DB_FS) { ($actual_db, $latest_time) = latest_file_modification_time($options, $filenames); } elsif ($db == DB_SCM) { ($actual_db, $latest_time) = latest_scm_modification_time($options, $filenames); } my $datetime = POSIX::strftime(expand_db_source($actual_db, $options->{DATETIME_FORMAT}), $options->{DATETIME_FUNCTION}($latest_time)); print "$datetime\n"; } sub main { my $options = {DATABASE => 'file-system', DATETIME_FORMAT => "%Y-%m-%d%q", DATETIME_FUNCTION => \&gm_time, VERBOSE => 0}; get_options($options); die("$COMMAND_NAME: no files given\n", "Try ", quote("$COMMAND_NAME --help"), " for more information.\n") unless @ARGV; my @filenames = filter_exisiting_files(@ARGV); die("$COMMAND_NAME: none of files given does exist\n") unless @filenames; if ($options->{VERBOSE} && @filenames < @ARGV) { print STDERR ("$COMMAND_NAME: info: ", scalar @filenames, " of ", scalar @ARGV, " files exist\n"); } show_last_update($options, \@filenames); return 0; } main(); enblend-enfuse-4.2/doc/OpenFile.pm0000644000175000017500000000206212562565245014012 00000000000000# name: OpenFile.pm # synopsis: open file or device in the OO way # author: Dr. Christoph L. Spiel # perl version: 5.20.2 # This file is part of Enblend. # Licence details can be found in the file COPYING. package OpenFile; use strict; use warnings; use Carp; use English; use IO::File; use IO::Handle; use Quote (); sub quote {Quote::gnu_style(@_)} sub open_file { my ($file, $mode) = @_; my $handle; $mode = 'r' unless $mode; if ($file eq '-') { $handle = new IO::Handle; if ($mode eq 'r') { $handle->fdopen(fileno(STDIN), 'r') or croak("cannot open standard input: $OS_ERROR"); } elsif ($mode eq 'w') { $handle->fdopen(fileno(STDOUT), 'w') or croak("cannot open standard output: $OS_ERROR"); } else { croak("internal error, unknown file mode ", quote($mode)); } } else { $handle = new IO::File($file, $mode) or croak("cannot open ", quote($file), ": $OS_ERROR"); } return $handle; } 1; enblend-enfuse-4.2/doc/log-transform.gp0000644000175000017500000000050212566032753015067 00000000000000# Show the "Log" transform we use to convert floating-point data # before copying it into a pyramid. LogTransform(x) = x >= 0.0 ? 1.0 + log(1.0 + x) : 1.0 / (1.0 - x); set grid set samples 1023 set xlabel "$L$" set ylabel "$\\mbox{Log}(L)$" unset key load DATA_DIR . "/colors.gp" plot [-20 : 100] LogTransform(x) enblend-enfuse-4.2/doc/static-preamble.tex0000644000175000017500000000556712676175561015572 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \RequirePackage[l2tabu, orthodox]{nag} \usepackage{amsmath} % align, align* \usepackage{bold-extra} % Bold typewriter for programming language keywords \usepackage{color} % \colorbox \usepackage{enumitem} % Extends environment `enumerate' \usepackage{footnote} % \makesavenoteenv \usepackage{graphicx} % \includegraphics \usepackage{epstopdf} \usepackage{hevea} \usepackage{hyphenat} % \hyp \usepackage{ifpdf} % \ifpdf \usepackage{latexsym} % \Box \usepackage{listings} \usepackage{microtype} % Improve spacing between words or letters \usepackage{ragged2e} % Improve hyphenation after e.g. \raggedright \usepackage{shorttoc} \usepackage{suffix} % \WithSuffix for the definition of starred macros \usepackage{url} % See: /usr/share/doc/texlive-doc/latex/url/url.pdf \usepackage{xstring} % \IfBeginWith, \StrGobbleLeft \input{macros} \input{index-def} \input{htmlstyle} \input{url-def} \input{config-h} % Help graphicx package when this document is processed by something else than original LaTeX. % Without intervention other processors happily pull in PNG-files, which belong to the HTML % version. \DeclareGraphicsExtensions{.eps,.pdf} \ifpdf \hyperreftrue \fi \ifhyperref \usepackage{hyperref} % MUST BE LOADED LATE! See: https://www.tug.org/applications/hyperref/manual.html \usepackage[all]{hypcap} % MUST BE LOADED AFTER `hyperref' package! \hypersetup{% colorlinks = true, % color the links themselves, do not use ghastly boxes linkcolor = navyblue, % use color as defined in "html-style.tex" linktocpage = true, % color page numbers not their contents lines raiselinks = false, urlcolor = skyblue, % use color as defined in "html-style.tex" } \fi \providecommand\phantomsection{} % define `\phantomsection' if hyperref is not included \pagestyle{myheadings} \renewcommand{\chaptermark}[1]{\markboth{\MakeUppercase{\chaptername\ \thechapter.\ #1}}{}} \renewcommand{\sectionmark}[1]{\markright{\MakeUppercase{\thesection.\ #1}}} %% Our preferred LaTeX document classes enumerate equations at chapter level. For consistency %% we need that for Hevea, too. \ifhevea \renewcommand{\theequation}{\thechapter.\arabic{equation}} \fi \tocnumber % let Hacha put section numbers into table-of-contents entries \ifhevea \relax \else \ifreferencemanual \relax \else \maxipagerulefalse \fi \fi \hyphenation{% ba-roque cat-ches chro-mi-n-ance DC-Raw En-blend En-fuse en-tro-py gray-scale Im-age-Mag-ick lo-rentz-ian lu-mi-n-ance meth-od mim-ic mo-no-chrome Open-CL Open-EXR Open-MP pa-no-ra-ma Raw-Therapee sour-ces UF-Raw } %HEVEA \footerfalse % Disable hevea advertisement in footer %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enblend.tex0000644000175000017500000000217412676175553014115 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \RequirePackage{fixltx2e} \input{dynamic-preamble} \ifreferencemanual \documentclass[\documentclassoptions]{refrep} \else \documentclass[\documentclassoptions]{report} \fi \input{static-preamble} \input{enblend-variables} \input{enblend-version} \newif\ifenblend\enblendtrue \newif\ifenfuse\enfusefalse \newcommand*{\App}{\application{Enblend}} \newcommand*{\app}{enblend} \newcommand*{\appcmd}{\command{enblend}} \newcommand*{\appdoes}{blend} \newcommand*{\appdid}{blended} \newcommand*{\OtherApp}{\application{Enfuse}} \newcommand*{\otherapp}{enfuse} \newcommand*{\otherappcmd}{\command{enfuse}} \finishdynamicpreamble \begin{document} \input{enblend-title} \input{lead-in} \include{enblend-overview} \include{common-known-limitations} \include{common-workflow} \include{enblend-invocation} \include{enblend-seam-generators} \include{enblend-visualization-image} \include{common-color-spaces} \include{common-understanding-masks} \input{lead-out} \end{document} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/floatstyle-ruledbot.sty0000644000175000017500000000116612667245144016523 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. %% Define a new `float' style. %% - Ruled: Draw rules before and after the float (and its caption). %% - Bot: Put the caption at the bottom of the float. \makeatletter \newcommand\fs@ruledbot{% \def\@fs@rule{\kern0pt\hfill\rule{.667\textwidth}{.333pt}\hfill\kern0pt\relax}% \def\@fs@cfont{\rmfamily}% \let\@fs@capt\floatc@ruled \def\@fs@pre{\@fs@rule\vspace\abovedisplayskip\relax}% \def\@fs@mid{\vspace\abovecaptionskip\relax}% \def\@fs@post{\vspace\belowcaptionskip\@fs@rule}% \let\@fs@iftopcapt\iffalse} \makeatother enblend-enfuse-4.2/doc/common-layer-selection.tex0000644000175000017500000002377612676175561017105 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Layer Selection\commonpart]{\label{sec:layer-selection}% \genidx[\rangebeginlocation]{layer!selection}% Layer Selection\commonpart} Some image formats, like for example \acronym{TIFF}, allow for storing more than one image in a single file, where all the contained images can have different sizes, number of channels, resolutions, compression schemes, etc. The file there acts as a container for an \emph{ordered} set of images. \genidx[\defininglocation]{file!multi-page}% \gensee{multi-page file}{file, multi-page}% \gensea{multi-page file}{layer}% \genidx[\defininglocation]{image!directory}% \genidx[\defininglocation]{layer!image}% In the \acronym{TIFF}-documentation these are known as ``multi-page'' files and because the image data in a \acronym{TIFF}-file is associated with a ``directory'', the files sometimes are also called ``multi-directory'' files. In this manual, multiple images in a file are called ``layers''. The main advantage of multi-layer files over a set of single-layer ones is a cleaner work area with less image-files and thus an easier handling of the intermediate products which get created when generating a panorama or fused image, and in particularly with regard to panoramas of fused images. The difficulty in working with layers is their lack of a possibly mnemonic naming scheme. They do not have telling names like \filename{taoth-vaclarush} or \filename{valos-cor}, but only numbers. \subsection[Layer Selection Syntax]{\label{sec:layer-selection-syntax}% \genidx{layer selection syntax}% \genidx{syntax!layer selection}% Layer Selection Syntax} To give the user the same flexibility in specifying and ordering images as with single-layer images, both \App{} and \OtherApp{} offer a special syntax to select layers in multi-page files by appending a \metavar{layer-specification} to the image file name. \tableName~\ref{tab:layer-selection-grammar} defines the grammar of \metavar{layer-specification}\/s. Selecting a tuple of layers with a \metavar{layer-specification} overrides the active layer selection algorithm. See also option~\flexipageref{\option{--layer-selector}}{opt:layer-selector} and \sectionName~\fullref{sec:response-files}. Layer selection works at the command-line as well as in Response Files; see \sectionName~\ref{sec:response-files}. \begin{table} \begin{tabular}{l@{$\quad::=\quad$}l} \metavar{layer-specification} & \sample{\val*{val:LAYERSPEC_OPEN}} \metavar{selection-tuple} \sample{\val*{val:LAYERSPEC_CLOSE}} \\ \metavar{selection-tuple} & \metavar{selection} [ \sample{:} \metavar{selection} ] \\ \metavar{selection} & \{ \metavar{singleton} $|$ \metavar{range} \} \\ \metavar{range} & [ \sample{\val*{val:layer-range-reverse-keyword}} ] [ \metavar{range-bound} ] \sample{\val*{val:layer-range-separator}} [ \metavar{range-bound} ] \\ \metavar{range-bound} & \metavar{singleton} $|$ \sample{\val*{val:layer-range-empty-index-symbol}} \\ \metavar{singleton} & \metavar{index} $|$ \sample{-} \metavar{index} \\ \end{tabular} where \metavar{index} is an integral layer index starting at one. \caption[Grammar of layer specifications]{\label{tab:layer-selection-grammar}% \genidx{syntax!layer selection!grammar}% \acronym{EBNF} definition of the grammar of layer specifications. In addition to the \metavar{selection} separator~\sample{:} shown all usual numeric-option delimiters (\sample{\val{val:numeric-option-delimiters}}) apply. The keyword for \metavar{range} reversal, \sample{\val{val:layer-range-reverse-keyword}}, can be abbreviated to any length and is treated case-insensitively.} \end{table} The simplest \metavar{layer-specification} are the layer-\metavar{index}es. The first layer gets index~1, the second layer~2, and so on. Zero never is a valid index! For convenience indexing backwards\footnotemark{} is also possible. This means by prefixing an index with a minus-sign~(\sample{-}) counting will start with the last layer of the \emph{associated} multi-page image, such that the last layer always has index~\code{-1}, the next to last index~\code{-2} and so on. Out-of-range indexes are silently ignored whether forward or backward. \footnotetext{\genidx{Carter, Samantha@\propername{Carter, Samantha}}\propername{Samantha Carter}: ``There has to be a way to reverse the process. The answer has to be here.''} The single layer of a single-layer file always can be accessed either with index~\sample{1} or \sample{-1}. Select a contiguous \metavar{range} of indexes with the range operator~\sample{\val{val:layer-range-separator}}, where the \metavar{range-bound}\/s are forward or backward indices. Leaving out a bound or substituting the open-range indicator~\sample{\val{val:layer-range-empty-index-symbol}} means a maximal range into the respective direction. Layer specifications ignore white space, but usual shells do not. This means that at the command-line \begin{terminal} \$ \app{} --output=out.tif --verbose multi-layer.tif[2:] \end{terminal} \noindent works, whereas spaced-out out phrase \sample{multi-layer.tif [2 : ]} must be quoted \begin{terminal} \$ \app{} --output=out.tif --verbose 'multi-layer.tif[2 : ]' \end{terminal} Quoting will also be required if \App's delimiters have special meanings to the shell. \smallskip Examples for an image with 8~layers. \begin{codelist} \newcommand*{\lspec}[1]{\mbox{\val*{val:LAYERSPEC_OPEN}{#1}\val*{val:LAYERSPEC_CLOSE}}}% \item[\lspec{}] The empty selection selects nothing and in that way works like the layer-selector \sample{no-layer}. \item[\lspec{2 :\ 4 :\ 5}] Select only layers~2, 4, and~5 in this order. \item[\lspec{2 :\ -4 :\ -3}] Like before, but with some backwards-counting indices. \item[\lspec{1 \val*{val:layer-range-separator}\ 4}] Layers 1~to 4, this is 1, 2, 3, and~4 in this order. \item[\lspec{\val*{val:layer-range-empty-index-symbol}\ \val*{val:layer-range-separator}\ 4}] Same as above in open-range notation. \item[\lspec{\val*{val:layer-range-separator}\ 4}] Same as above in abbreviated, open-range notation. \item[\lspec{-2 \val*{val:layer-range-separator}\ \val*{val:layer-range-empty-index-symbol}}] The last two layers, which are~7 and~8 in our running example. \item[\lspec{\val*{val:layer-range-empty-index-symbol}\ \val*{val:layer-range-separator}\ \val*{val:layer-range-empty-index-symbol}}] All layers in their natural order. \item[\lspec{\val*{val:layer-range-separator}}] All layers in their natural order selected with the abbreviated notation. \item[\lspec{reverse \val*{val:layer-range-empty-index-symbol}\ \val*{val:layer-range-separator}\ \val*{val:layer-range-empty-index-symbol}}] All layers in reverse order. This yields 8, 7, 6, 5, 4, 3, 2, and~1. \item[\lspec{rev \val*{val:layer-range-separator}}] All layers in reversed order as before selected with the abbreviated notation. \item[\lspec{r -3 \val*{val:layer-range-separator}}] The last three layers in reverse order, this is 8, 7 and~6 in our running example. \end{codelist} \begin{geeknote} Shell expansion will not work anymore with a file name terminated by a layer specification expression (or anything else), because to the shell it is not a file name anymore. Work around with, for example, \begin{terminal} \$ \app{} `for x in image-??.tif; do echo \$x[2]; done` \end{terminal} \noindent or \begin{terminal} \$ \app{} \$(ls -1 image-??.tif | sed -e 's/\$/[2]/') \end{terminal} The order of the indices determines the order of the layers, this is, the images. An index can occur multiple times, which causes layer to be considered \emph{again}. Consequently, this will lead to an error with \application{Enblend}, but may be desired with \application{Enfuse} in \code{soft-mask}~mode to give the image more weight by mentioning it more than once. \end{geeknote} \subsection[Tools for Multi-Page Files]{\label{sec:tools-for-multi-page-files}% \genidx{multi-page file!tools}% Tools for Multi-Page Files} Here are some tools that are particularly useful when working with multi-page files. For more helpful utilities check out \appendixName~\fullref{sec:helpful-programs}. \begin{itemize} \item \appidx{Hugin}\application{Hugin}'s stitcher, \prgidx{nona \textrm{(Hugin)}}\command{nona} produces multi-page \acronym{TIFF}~file, when called with the \sample{-m TIFF\_multilayer}-option. \item The utility \prgidx{tiffcp \textrm{(LibTIFF)}}\command{tiffcp} of the \acronym{TIFF}-\uref{\remotesensingorglibtiff}{LibTIFF tool suite} merges several \acronym{TIFF}-images into a single multi-page file. \item The sister program \prgidx{tiffsplit \textrm{(LibTIFF)}}\command{tiffsplit} splits a multi-page file into a set of single-page \acronym{TIFF}-images. \item Another utility of the same origin, \prgidx{tiffinfo \textrm{(LibTIFF)}}\command{tiffinfo}, is very helpful when inquiring the contents of single- or multi-page file \acronym{TIFF}-files. \genidx{image!frame} \item All tools of the \uref{\imagemagickorg}{\application{ImageMagick}}-suite, like, for example, \prgidx{convert \textrm{(ImageMagick)}}\command{convert} and \prgidx{display \textrm{(ImageMagick)}}\command{display} use a \uref{\imagemagickorgcommandlineprocessinginput}{similar syntax} as \App{} to select layers (which in \application{ImageMagick} parlance are called ``frames'') in multi-page files. Please note that \application{ImageMagick} tools start indexing at zero, whereas we start at one. \item \App{} and \OtherApp{} by default apply the \sample{\val{val:layer-selector}} selector (see option~\flexipageref{\option{--layer-selector}}{opt:layer-selector}) to each of the input images. \end{itemize} Please bear in mind that some image-processing tools -- none of the above though -- do \emph{not} handle multi-page files correctly, where the most unfruitful ones only take care of the first layer and \emph{silently} ignore any further layers. \genidx[\rangeendlocation]{layer!selection} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/index-def.tex0000644000175000017500000000575712560674445014357 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \usepackage{index} \makeindex \newindex{general}{gdx}{gnd}{General Index} \newindex{option}{odx}{ond}{Option Index} % command-line options \newindex{program}{pdx}{pnd}{Program/\hspace{-.167em}Application Index} \newindex{syncomm}{adx}{and}{Syntactic Comment Index} % syntactic comments in response files %% %% Level 1 Index Generation %% \newcommand*{\normallocation}{normal location} \newcommand*{\defininglocation}{defining location} \newcommand*{\summarylocation}{summary location} \newcommand*{\rangebeginlocation}{range-begin location} \newcommand*{\rangeendlocation}{range-end location} %% \makefancyindex %% #1: name of index (program, option, general, ...) %% #2: location macro (\normallocation, \defininglocation, ...) %% #3: (possibly decorated) index item \newcommand*{\makefancyindex}[3]{% \ifx\normallocation#2% \index[#1]{#3}% \else \ifx\defininglocation#2% \index[#1]{#3|underline}% \else \ifx\summarylocation#2% \index[#1]{#3|textsl}% \else \ifx\rangebeginlocation#2% % Downgrade range-begin to a normal index entry for Hevea/HTML \ifhevea \index[#1]{#3}\else \index[#1]{#3|(}\fi \else \ifx\rangeendlocation#2% % Range-ends make little sense for Hevea/HTML \ifhevea \relax \else \index[#1]{#3|)}\fi \else \index[#1]{???: #3}% \fi \fi \fi \fi \fi } \newcommand*{\appidx}[2][\normallocation]% program/application name index: application name {\makefancyindex{program}{#1}{\application{#2}}} \newcommand*{\genidx}[2][\normallocation]{\makefancyindex{general}{#1}{#2}} \newcommand*{\optidx}[2][\normallocation]% command-line option index {\makefancyindex{option}{#1}{\option{#2}}} \newcommand*{\prgidx}[2][\normallocation]% program/application name index: command name {\makefancyindex{program}{#1}{\code{#2}}} \newcommand*{\shoptidx}[2]{\index[option]{\option{#1} (long: \option{#2})}} \newcommand*{\synidx}[1]{\index[syncomm]{\code{#1}}}% syntactic comment index %% %% Level 2 Index Generation -- Cross-References %% %% \seexref %% #1: final index term %% #2: page number, which we want to drop \newcommand*{\seexref}[2]{\textit{see\/} #1} %% \seealsoxref %% #1: final index term %% #2: page number \newcommand*{\seealsoxref}[2]{\newline\textit{see also\/} #1, #2} %% \makefancyreference %% #1: name of index (program, option, general, ...) %% #2: one-argument cross-reference macro, e.g. \seexref or \seealsoxref %% #3: indirecting index item %% #4: final index term \newcommand*{\makefancyreference}[4]{\index[#1]{#3|#2{#4}}} \newcommand*{\gensee}[2]{\makefancyreference{general}{seexref}{#1}{#2}} \newcommand*{\gensea}[2]{\makefancyreference{general}{seealsoxref}{#1}{#2}} %--\proofmodetrue %%% Local Variables: %%% fill-column: 96 %%% mode: latex %%% End: enblend-enfuse-4.2/doc/docstrings0000755000175000017500000002363212665527065014070 00000000000000#! /usr/bin/env perl # This file is part of Enblend. # Licence details can be found in the file COPYING. # name: docstrings # synopsis: extract documentation strings from text files # or produce key/value pairs for TeX # author: Dr. Christoph L. Spiel # perl version: 5.20.2 use strict; use warnings; use English; use File::Basename (); use FindBin qw($Bin); use Getopt::Long; use Readonly; use lib $Bin; use OpenFile; use Quote (); use TexAux (); Readonly my $COMMAND_NAME => File::Basename::basename($PROGRAM_NAME); sub quote {Quote::gnu_style(@_)} sub write_support_code { my ($options) = @_; my $insert = $options->{INSERT_MACRO_NAME}; my $find = $options->{FIND_MACRO_NAME}; my @result = (qq(%% This piece of TeX-code was automatically generated with $COMMAND_NAME.), q(%%), q(%% Define a key-value pair with `) . $insert . q({KEY}{VALUE}'. Reference), q(%% it like any other label, this is, say `). $find . q({KEY}' to recover), q(%% VALUE.), q(\def) . $insert . q(#1{\expandafter\def\csname valuehash(#1)\endcsname}), q(\def) . $find . q(#1{\csname valuehash(#1)\endcsname}), q()); print join("\n", @result); } my $regexp = qr{ // # C++-style comment \s* # optional whitespace < # docstring-indicator character \s* # optional whitespace (\S+) # key: anything but whitespace \s+ # whitespace (.*) # value: capture rest of string | # or /\* # C-style comment begin \s* # optional whitespace < # docstring-begin indicator character \s* # optional whitespace (\S+) # key: anything but whitespace \s+ # whitespace (.*?) # non-greedy capture \s* # optional whitespace > # docstring-end indicator character \s* # optional whitespace \*/ # C-style comment end }x; sub insert_docstring { my ($docstrings, $data) = @_; my $key = $data->{KEY}; #-- my $value = $data->{VALUE}; # currently unused die "$COMMAND_NAME: empty key at $data->{FILENAME}:$data->{LINENUMBER};\n" unless $key; if (exists $docstrings->{$key}) { my $previous_file = $docstrings->{$key}{FILENAME}; my $previous_line = $docstrings->{$key}{LINENUMBER}; my $quoted_key = quote($key); warn("$COMMAND_NAME: warning: duplicate key $quoted_key at $data->{FILENAME}:$data->{LINENUMBER};\n", "$COMMAND_NAME: warning: previous definition at $previous_file:$previous_line\n"); } $docstrings->{$key} = $data; } sub collect_docstrings { my ($docstrings, $filename, $file) = @_; my $basename = File::Basename::basename($filename); my $linenumber = 1; while (my $line = readline $file) { while ($line =~ m{$regexp}g) { insert_docstring($docstrings, {FILENAME => $basename, LINENUMBER => $linenumber, KEY => $1, VALUE => $2}); } ++$linenumber; } return $docstrings; } sub print_docstrings { my ($options, $docstrings) = @_; print "% This TeX-file was automatically generated with $COMMAND_NAME.\n\n"; foreach my $key (sort keys %$docstrings) { my $filename = $docstrings->{$key}{FILENAME}; my $linenumber = $docstrings->{$key}{LINENUMBER}; my $raw_value = $docstrings->{$key}{VALUE}; my $value = TexAux::escape(defined($raw_value) ? $raw_value : $options->{EMPTY_VALUE_SUBSTITUTE}); if ($key =~ m#DIR|PATH#) { $value = TexAux::lift($value); } print("%% $filename:$linenumber\n", "$options->{INSERT_MACRO_NAME}\{$options->{KEY_PREFIX}$key\}\{$value\}\n", "\n"); } } sub scan_file { my ($docstrings, $input_filename) = @_; my $input_file = OpenFile::open_file($input_filename); collect_docstrings($docstrings, $input_filename, $input_file); $input_file->close or warn("$COMMAND_NAME: cannot close input file ", quote($input_filename), ": $OS_ERROR\n"); } sub collect_pairs { my ($docstrings, @key_value_pairs) = @_; if (@key_value_pairs % 2 == 1) { warn "$COMMAND_NAME: odd number of arguments -- will drop last to form pairs\n"; pop @key_value_pairs; } my %pairs = @key_value_pairs; my $i = 1; while (my ($key, $value) = each %pairs) { insert_docstring($docstrings, {FILENAME => '', LINENUMBER => $i, # recycle line-number field for pair index KEY => $key, VALUE => $value}); $i++; } } sub read_list_from_file { my %args = (SOURCE => '-', SEPARATOR => "\n", @_); local $INPUT_RECORD_SEPARATOR = $args{SEPARATOR}; my @result; my $file = OpenFile::open_file($args{SOURCE}); while (my $record = readline $file) { chomp $record; push @result, $record; } $file->close; return @result; } sub show_help { my $options = shift; my ($quoted_scan_file, $quoted_key_value, $quoted_write_support_code, $quoted_double_slash, $quoted_less_than, $quoted_greater_than, $quoted_begin_comment, $quoted_end_comment, $quoted_insert, $quoted_find, $quoted_prefix) = map {quote($_)} ('scan-file', 'key-value', 'write-support-code', '//', '<', '>', '/*', '*/', $options->{INSERT_MACRO_NAME}, $options->{FIND_MACRO_NAME}, $options->{KEY_PREFIX}); print < \$options->{INSERT_MACRO_NAME}, 'find-macro=s' => \$options->{FIND_MACRO_NAME}, 'prefix=s' => \$options->{KEY_PREFIX}, 'xargs' => sub {$options->{READ_FROM_STDIN} = "\n"}, 'xargs0' => sub {$options->{READ_FROM_STDIN} = "\0"}, 'no-xargs|no-xargs0' => sub {$options->{READ_FROM_STDIN} = undef}, 'h|help' => sub {show_help($options)}) or warn "$COMMAND_NAME: problems while parsing options\n"; } sub main { my $options = {READ_FROM_STDIN => undef, EMPTY_VALUE_SUBSTITUTE => 'N/A', KEY_PREFIX => TexAux::default_name('KEY_PREFIX'), INSERT_MACRO_NAME => TexAux::default_name('INSERT_MACRO_NAME'), FIND_MACRO_NAME => TexAux::default_name('FIND_MACRO_NAME')}; get_options($options); die "$COMMAND_NAME: missing operation-mode argument\n" unless @ARGV; my $docstrings = {}; my $mode_argument = shift @ARGV; my $mode = lc $mode_argument; my @arguments = @ARGV; if ($options->{READ_FROM_STDIN}) { @arguments = (@arguments, read_list_from_file(SEPARATOR => $options->{READ_FROM_STDIN})); } if ($mode =~ m#^keys?-values?$#) { collect_pairs($docstrings, @arguments); } elsif ($mode =~ m#^scan-files?$#) { push(@arguments, "-") unless @arguments; scan_file($docstrings, $_) foreach @arguments; } elsif ($mode eq 'write-support-code') { write_support_code($options); exit 0; } else { die("$COMMAND_NAME: unknown operation mode ", quote($mode_argument), "\n"); } print_docstrings($options, $docstrings); return 0; } main(); enblend-enfuse-4.2/doc/enblend-invocation.tex0000644000175000017500000000226212667236617016261 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Invocation]{\label{sec:invocation}% \genidx[\rangebeginlocation]{invocation}% \genidx{command-line}% Invocation} %HEVEA\cutdef{section} \noindent Assemble the sequence of images \metavar{INPUT}\dots{} into a single \metavar{IMAGE}. \smallskip \code{\app} \optional{\metavar{OPTIONS}} \optional{\option{--output=}\metavar{IMAGE}} \metavar{INPUT}\dots \smallskip \genidx{filename!literal}% \gensee{literal filename}{filename, literal}% \genidx{file!response}% \gensee{response file}{file, response}% \noindent \metavar{INPUT} images are either specified literally or via so-called response files (see \sectionName~\ref{sec:response-files}). The latter are an alternative to specifying image filenames on the command line. If omitted, the name of the output \metavar{IMAGE} defaults to \filename{\val{val:default-output-filename}}. \input{enblend-image-requirements} \input{enblend-options} \input{common-option-delimiters} \input{common-response-files} \input{common-layer-selection} \genidx[\rangeendlocation]{invocation} %HEVEA\cutend %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/common-mask-template-characters.tex0000644000175000017500000000700712667245423020647 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \begin{table} \centering \begin{tabular}{cp{.8\linewidth}} \hline \multicolumn{1}{c|}{Format} & \multicolumn{1}{c}{Interpretation} \\ \hline\extraheadingsep \genidx{mask!template character!\%@\sample{\%}}\code{\%\%} & Produces a literal \sample{\%}-sign. \\ \genidx{mask!template character!i@\sample{i}}\code{\%i} & Expands to the index of the mask file starting at zero. \sample{\%i} allows for setting a pad character or a width specification: \begin{literal} \% \metavar{PAD} \metavar{WIDTH} i \end{literal} \metavar{PAD} is either \sample{0} or any punctuation character; the default pad character is \sample{0}. \metavar{WIDTH} is an integer specifying the minimum width of the number. The default is the smallest width given the number of input images, this is 1 for 2--9~images, 2 for 10--99~images, 3 for 100--999~images, and so on. Examples: \sample{\%i}, \sample{\%02i}, or \sample{\%\_4i}. \\ \genidx{mask!template character!n@\sample{n}}\code{\%n} & Expands to the number of the mask file starting at one. Otherwise it behaves identically to \sample{\%i}, including pad character and width specification. \\ \genidx{mask!template character!p@\sample{p}}\code{\%p} & This is the full name (path, filename, and extension) of the input file associated with the mask. Example: If the input file is called \filename{/home/luser/snap/img.jpg}, \sample{\%p} expands to \filename{/home/luser/snap/img.jpg}, or shorter: \sample{\%p} \result{} \filename{/home/luser/snap/img.jpg}. \\ \genidx{mask!template character!P@\sample{P}}\code{\%P} & This is the full name of the output file. \\ \genidx{mask!template character!d@\sample{d}}\code{\%d} & Is replaced with the directory part of the associated input file. Example (cont.): \sample{\%d} \result{} \filename{/home/luser/snap}. \\ \genidx{mask!template character!D@\sample{D}}\code{\%D} & Is replaced with the directory part of the output file. \\ \genidx{mask!template character!b@\sample{b}}\code{\%b} & Is replaced with the non-directory part (often called ``basename'') of the associated input file. Example (cont.): \sample{\%b} \result{} \filename{img.jpg}. \\ \genidx{mask!template character!B@\sample{B}}\code{\%B} & Is replaced with the non-directory part of the output file. \\ \genidx{mask!template character!f@\sample{f}}\code{\%f} & Is replaced with the filename without path and extension of the associated input file. Example (cont.): \sample{\%f} \result{} \filename{img}. \\ \genidx{mask!template character!F@\sample{F}}\code{\%F} & Is replaced with the filename without path and extension of the output file. \\ \genidx{mask!template character!e@\sample{e}}\code{\%e} & Is replaced with the extension (including the leading dot) of the associated input file. Example (cont.): \sample{\%e} \result{} \filename{.jpg}. \\ \genidx{mask!template character!E@\sample{E}}\code{\%E} & Is replaced with the extension of the output file. \end{tabular} \caption[Mask template characters]{\label{tab:mask-template-characters}% \genidx[\summarylocation]{mask!template character}% Special format characters to control the generation of mask filenames. Uppercase letters refer to the output filename and lowercase ones to the input files.} \end{table} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/halfsine.gp0000644000175000017500000000132412566032753014071 00000000000000default_optimum = 0.5 default_width = 0.2 fwhm_gaussian = 2.3548200450309493820231386529193992755 fwhm_halfsinusodial = 2.0943951023931954923084289221863352561 halfsine(y, y_opt, width) = \ abs((y - y_opt) / (width * fwhm_gaussian / fwhm_halfsinusodial)) <= pi / 2.0 ? \ cos((y - y_opt) / (width * fwhm_gaussian / fwhm_halfsinusodial)) : \ 0 set key bmargin center horizontal set samples 1023 set xlabel "$Y$" set xtics 0.2 set ylabel "$w$" set ytics 0.2 load DATA_DIR . "/colors.gp" plot [y = 0:1] \ halfsine(y, default_optimum, 0.1) title "width = 0.1", \ halfsine(y, default_optimum, 0.2) title "default width = 0.2", \ halfsine(y, default_optimum, 0.4) title "width = 0.4" enblend-enfuse-4.2/doc/macros.tex0000644000175000017500000003315012676175561013767 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. %% Words and abbreviations \newcommand*{\appendixName}{Appendix} \newcommand*{\appendixabbr}{App.} \newcommand*{\chapterName}{Chapter} \newcommand*{\chapterabbr}{Ch.} \newcommand*{\equationabbr}{Eqn.} \newcommand*{\equationName}{Equation} \newcommand*{\exampleabbr}{Ex.} \newcommand*{\exampleName}{Example} \newcommand*{\figureabbr}{Fig.} \newcommand*{\figureName}{Figure} \newcommand*{\pageabbr}{p.} \newcommand*{\pagename}{page} \newcommand*{\sectionabbr}{Sec.} \newcommand*{\sectionName}{Section} \newcommand*{\tableabbr}{Tab.} \newcommand*{\tableName}{Table} \newcommand*{\LogTransform}{\mbox{Log}} % Enblend/Enfuse luminance transform %% Texinfo compatibility macros \newcommand*{\acronym}[1]{\textsc{#1}} \newcommand*{\code}[1]{\texttt{#1}} \newcommand*{\command}[1]% command name in running text; use \code everywhere else {\ifhevea\textbf{#1}\else{\fontseries{b}\selectfont #1}\fi} \newcommand*{\dmn}[1]{\,#1} \newcommand*{\envvar}[1]{\texttt{#1}} % Texinfo: `@env' \newcommand*{\filename}[1]{\textit{#1}} % Texinfo: `@file' \newcommand*{\metavar}[1]{\textsl{#1}} % Texinfo: `@var' \newcommand{\option}[1]{\texttt{% %% We want to make long-name options (implicitly) hyphenatable in the printable document, %% however the initial two dashes must never be hyphenation points. \ifhevea #1\else \IfBeginWith{#1}{--}% {\mbox{--}\begin{makehyphenatable}{\ttfamily}\StrGobbleLeft{#1}{2}\end{makehyphenatable}}% {#1}\fi }} \WithSuffix\newcommand\option*[1]{\mbox{\texttt{#1}}} % Texinfo: `@option' \newcommand*{\sample}[1]{\mbox{`\texttt{#1}'}} % Texinfo: `@samp' \newcommand*{\strong}[1]{\textbf{#1}} \newcommand*{\abbreviation}[2][\relax]{\ifx\relax#1{#2}\else{#2~(#1)}\fi} %% Configure look of footnote marks for the printable versions. See "source2e.pdf", Sec. 62.2. \ifhevea\relax\else \renewcommand{\thefootnote}{\oldstylenums{\arabic{footnote}}} \makeatletter \let\prev@makefnmark\@makefnmark \def\@makefnmark{\prev@makefnmark\hspace*{-.0625em})}% Very old style! \long\def\@makefntext#1{\RaggedRight\parindent 1em\noindent\hb@xt@ 1.8em{\hss\@makefnmark}~#1} \makeatother \fi \newif\ifinfootnote \ifhevea\relax\else \let\oldfootnote\footnote \renewcommand{\footnote}[2]{\infootnotetrue\oldfootnote{#1}{#2}\infootnotefalse} \fi \newcommand*{\uref}[2]% Texinfo: `@uref{URL, LABEL}' {\ifhevea \footahref{#1}{#2}% See: http://hevea.inria.fr/doc/manual018.html#sec65 \else \ifinfootnote \ahref{#1}{#2} (#1)% Texinfo's clumsy style \else \footahref{#1}{#2}% Hevea's preferred style \fi \fi} \newcommand*{\urefval}[2]% {\ifhevea \indicatesourcevalue{\uref{\val*{#1}}{#2}}% \else \uref{\indicatesourcevalue{\val*{#1}}}{#2}% \fi} %% Use `\urlmark{URL}{LABEL}' inside an `\item' of a `description' list, i.e. inside the square %% brackets. Follow with `\urltext' outside the right square bracket. Example: %% \item[\urlmark{\urloffoo}{Foo}]\urltext \newcommand{\urlmark}[2]% {\ifhevea \footahref{#1}{#2}% \else {#2}\footnotemark\global\def\urlmarkargi{#1}\fi} \newcommand{\urltext}% {\ifhevea\relax \else\footnotetext{\texttt{\urlmarkargi}}\fi} %% Our own markup \newcommand*{\Ex}{\textsf{Ex}\,} % expectation value \newcommand*{\Var}{\textsf{Var}\,} % variance \newcommand*{\angulardegree}{\mbox{$^{\circ}$}} \newcommand*{\asterisk}{\mbox{$*$}} \newcommand*{\atsign}{\char64} \newcommand*{\bslash}{\char92} \newcommand*{\caret}{\char94} \newcommand*{\classictimes}{\mbox{$\times$}} \newcommand*{\commonpart}{\texorpdfstring{\mbox{$^{\textsf{c}}$}}{}} % Chapters, sections, etc. occurring on both manuals \newcommand*{\extraheadingsep}{\ifhevea\relax\else\rule{0pt}{3ex}\fi} % was: \rigidbaselineskip \newcommand*{\feasiblebreak}{\ifhevea\relax\else\linebreak[1]\fi} \newcommand*{\itemend}{\ifhevea \relax\else \leavevmode\newline \fi} \newcommand*{\oldstylefirst}{\mbox{$1^{\mathrm{st}}$}} \newcommand*{\oldstylesecond}{\mbox{$2^{\mathrm{nd}}$}} \newcommand*{\oldstylethird}{\mbox{$3^{\mathrm{rd}}$}} \newcommand*{\raisedasterisk}{\mbox{${}^{*}$}} \newcommand*{\result}{\mbox{$\mapsto$}} \newcommand*{\squiggle}{\char126} \newcommand*{\application}[1]{\mbox{\textsf{#1}}} \newcommand*{\conj}[1]{{#1}^\ast} % complex conjugate \newcommand*{\eqnref}[1]{(\ref{#1})} \newcommand{\fixme}[1]{\ifhevea\colorbox{\fixmebackgroundcolor}{FIX}\else\fbox{FIX}\fi {#1}% \ifhevea\colorbox{\fixmebackgroundcolor}{ME}\else\fbox{ME}\fi} \newcommand*{\fourier}[1]{\widehat{#1}} % Fourier-transformed variable \newcommand*{\fullref}[1]{\ifhevea \ref{#1}\else \ref{#1} on \pagename~\pageref{#1}\fi} \WithSuffix\newcommand\fullref*[1]{\ifhevea \ref{#1}\else \ref{#1}, \pageabbr~\pageref{#1}\fi} \newcommand*{\guielement}[1]{\textsc{#1}} %%\newcommand*{\hangingitem}{\ifhevea\relax\else\hangindent=2em\hangafter=1\fi} \newcommand{\itempar}[1]{\ifhevea #1\else \parbox[t]{.98\linewidth}{#1\vspace{.667ex}}\fi} \newcommand{\mainpurpose}[1]{\strong{Main Purpose:}~#1} \newcommand*{\symmgroup}[1]{\mathsf{#1}} \newcommand*{\oldstyleNth}[1]{\mbox{${#1}^{\mathrm{th}}$}} \newcommand*{\optional}[1]{$[$#1$]$} \newcommand*{\propername}[1]{\textsc{#1}} \newcommand*{\refrep}[1]{\tag{\ref{#1} rep.}} \newcommand{\restrictednote}[1]% {\ifhevea\colorbox{\restrictedmaterialbordercolor}{#1}\else\fbox{\textrm{#1}}\fi} \newcommand{\shifteven}[1]% shift a box down half of \baselineskip {\setbox1=\hbox{#1}\raisebox{-.5\rigidbaselineskip}[\ht1][\dp1]{#1}} \newcommand*{\transpose}[1]{{#1}^{\mathrm{T}}} % transposition \newcommand*{\flexipageref}[2]{\ifhevea\ahrefloc{#2}{#1}\else #1, \pagename~\pageref{#2}\fi} \WithSuffix\newcommand\flexipageref*[2]{\ifhevea\ahrefloc{#2}{#1}\else #1 (\pagename~\pageref{#2})\fi} \newcommand*{\manpage}[2]{#1(#2)} \newcommand*{\semilog}[2]{\mbox{${#1}\cdot 10^{#2}$}} % \cdot or \times \newcommand*{\slfrac}[2]% Knuth, answer to Question 11.6 rewritten with LaTeX macros {\ifhevea #1/#2\else \hspace{.1em}\raisebox{.5ex}{\scriptsize #1}\hspace{-.1em}/% \hspace{-.15em}\raisebox{-.25ex}{\scriptsize #2}% \fi} \def\itemx[#1]{\mbox{}\vspace*{-\itemsep}\vspace*{-\parsep}\item[#1]} %% Source-of-document-date on the title page \newcommand*{\datebyunknown}{\footnote{Date determined in some unknown, unreliable way.}} \newcommand*{\datebyfs}{\footnote{Date determined via file-system -- potentially inaccurate.}} \newcommand*{\datebyscm}{\footnote{Date reliably determined via source-code management system.}} %% Inclusion of graphics and images. Argument #1 passes additional directives to the sub-macro; %% argument #2 is the image filename. \newcommand{\includeimage}[2][]% {\ifhevea \imgsrc{#2.png}% \else \IfFileExists{#2.pstex}% {\input{#2.pstex}}% EPS(La)TeX file transporting PostScript inside a LaTeX envelope {\includegraphics[#1]{#2}}% Usually an Encapsulated PostScript file \fi} %% Pacify Hevea \ifhevea \def\WithSuffix{\relax} \def\caption[#1]#2{#2} \def\endappendix{\relax} \def\endexample{\relax} \def\endsavenotes{\relax} \def\example{\relax} \def\floatname{\relax} \def\floatstyle{\relax} \def\fontseries{\relax} \def\hyp{-} \def\listof{\relax} \def\makesavenoteenv{\relax} \def\newfloat{\relax} \def\obeylines{\relax} \def\oldstylenums{\relax} \def\overfullrule=#1{\relax} \def\savenotes{\relax} \def\selectfont{\relax} \def\slash{/} \fi \ifreferencemanual %% Class Refrep (``Reference Manual'') has no twocolumn layout. \def\twocolumn[#1]{#1} \fi %% Allow for some hyphenation of typewriter fonts. \newenvironment{makehyphenatable}[1]{#1\hyphenchar\the\font=`\=}{} \newcommand*{\signalinghyphenchar}{\char61}% `=' \newcommand*{\shyp}{\ifhevea\relax\else\discretionary{\signalinghyphenchar}{}{}\fi} %% Taken from Refman style and adapted. \newcommand{\declaremaxipagerule}{\newif\ifmaxipagerule\maxipageruletrue}% See Knuth, p211 \ifreferencemanual \relax \else \declaremaxipagerule \newlength{\maxipagewidth} \setlength{\maxipagewidth}{\textwidth} \addtolength{\maxipagewidth}{1.9\oddsidemargin} \newenvironment{maxipage}% {\par \makebox[-.95\oddsidemargin]{}% \begin{minipage}{\maxipagewidth}% \medskip \ifhevea \begin{divstyle}{maxipage}% \else \ifmaxipagerule \hrule\medskip \fi \parskip=.5\baselineskip \fi \def\marginpar{\typeout{Marginpar not allowed within `maxipage' environment.}}}% {\par % TeX: \vskip\parskip \medskip \ifhevea \end{divstyle}% \else \ifmaxipagerule \hrule\medskip \fi \fi \end{minipage}% \par}% \fi %% Program listings \lstdefinestyle{colors}{} \lstnewenvironment{cxxlisting}% {\setenvclass{lstlisting}{cxxlisting} \ifhevea \lstset{language=C++, commentstyle=\color{orangered}\textsl, keywordstyle=\color{violetblue}\textbf, stringstyle=\color{orchid}, style=colors} \else \lstset{language=C++, basicstyle={\small\ttfamily}, commentstyle=\textsl, keywordstyle=\textbf} \fi}% {} \lstnewenvironment{adalisting}% {\setenvclass{lstlisting}{adalisting} \ifhevea \lstset{language=Ada, style=colors} \else \lstset{language=Ada, basicstyle={\small\ttfamily}, commentstyle=\textsl, keywordstyle=\textbf} \fi}% {} %% Description list with definitions marked with `\code'. \newenvironment{codelist}% {\begin{list}{}{\renewcommand{\makelabel}[1]{\code{##1}}}}% {\end{list}} %% Decent Lists \newenvironment{compactenumerate}% {\ifhevea\begin{enumerate}\else \begin{enumerate}[noitemsep]\fi}% {\end{enumerate}} \newenvironment{compactitemize}% {\ifhevea\begin{itemize}\else \begin{itemize}[noitemsep]% \renewcommand{\labelitemi}{$-$}% \renewcommand{\labelitemii}{$\circ$}% \renewcommand{\labelitemiii}{$\box$}% \renewcommand{\labelitemiv}{$\cdot$}\fi}% {\end{itemize}} %% Material that is not essential, but that we do not want to see as footnotes. %% Use the macro like `{\geekytext foo\/}'. \newcommand{\geekytext}{\small\slshape} \ifhevea \newenvironment{geeknote}% {\begin{divstyle}{geeknote}\begin{quotation}\geekytext}% {\end{quotation}\end{divstyle}} \else \newenvironment{geeknote}% {\begin{savenotes}\fboxsep=0pt\begin{quotation}\RaggedRight\geekytext}% {\end{quotation}\end{savenotes}} \makesavenoteenv{geeknote} \fi %% Literal text as e.g. the contents of a text file. \newenvironment{literal}% {\pagebreak[1]\begin{divstyle}{literal}% \begin{trivlist}{}{\ifhevea\relax\else\topsep=0pt\fi}\item\relax \RaggedRight\frenchspacing\ttfamily}% {\end{trivlist}\end{divstyle}} %% Description list for summarizing options. \newenvironment{optionsummary}% {\medskip\pagebreak[1]\par\noindent\strong{Summary of influential options}% \begin{list}{}{\ifhevea\relax\else\topsep=0pt\leftmargin=4em\fi \renewcommand{\makelabel}[1]{\option{##1}:\ }}}% {\end{list}} %% Special list for `Question-and-Answer' items. Requires package `enumitem'. \newenvironment{qandalist}% {\ifhevea \begin{enumerate}\else \begin{enumerate}[label={\normalfont(\arabic*.)}]\fi \itshape} {\end{enumerate}} \newenvironment{qandaanswer}{\par\normalfont}{} %% Specially grouped quote. \newenvironment{sgquote} {\smallskip\begin{flushright}% \def\Author##1{\mbox{##1}}% Do not break the name of the author of the quote. \def\Quote##1{{\itshape ##1}}}% Typeset the quote itself in italics. {\end{flushright}\smallskip} %% Markup for material that applies only to a particular application, this is either Enblend or %% Enfuse, but not both. The markup e.g. applies to different operating systems, too. \newenvironment{restrictedmaterial}[1]% {\begin{savenotes}\begin{divstyle}{restrictedmaterial}\noindent\restrictednote{#1}\begin{quotation}}% {\end{quotation}% \ifhevea\relax\else\RaggedLeft\mbox{$\Box$}\par\fi \end{divstyle}\end{savenotes}} \makesavenoteenv{restrictedmaterial} %% Simulate terminal output. \newenvironment{terminal}% {\begin{divstyle}{terminal}\begin{flushleft}\frenchspacing\ttfamily}% {\end{flushleft}\end{divstyle}} %% Overwrite `description' environment, because Hevea's built-in definition is broken. Keep %% `description' for reference manual styles, but ditch the colon after description items. \ifreferencemanual \descriptioncolonfalse \else \renewenvironment{description}% {\begin{list}{}{\renewcommand{\makelabel}[1]{##1}}}% {\end{list}}% \fi %% Extra floating objects: exemplars. We cannot use `example', because the macro-name is used %% in `Reference-Manual' style. \input{floatstyle-ruledbot.sty} \ifhevea \input{exemplar.hva} \renewcommand{\exemplarname}{Example} \newcommand*{\listofexemplars}{\relax} \else \usepackage{float} \newfloat{exemplarbase}{btp}{lox}[chapter] \floatname{exemplarbase}{Example} \newenvironment{exemplar}[1][]% {\maxipagerulefalse \floatstyle{ruledbot}\restylefloat*{exemplarbase}\begin{exemplarbase}[#1]}% {\end{exemplarbase}} \newenvironment{exemplar*}[1][]% {\floatstyle{plain}\restylefloat*{exemplarbase}\begin{exemplarbase}[#1]}% {\end{exemplarbase}} \fi %% Define a key-value pair with `\hashinsert{KEY}{VALUE}'. Reference it like any other label, %% this is, say `\hashfind{KEY}' to recover VALUE. \def\hashinsert#1{\expandafter\def\csname valuehash(#1)\endcsname} \def\hashfind#1{\csname valuehash(#1)\endcsname} \newcommand*{\indicatesourcevalue}[1]{\mbox{$\langle${#1}\/$\rangle$}} \newcommand*{\val}[1]{\indicatesourcevalue{\hashfind{#1}}} \WithSuffix\newcommand\val*[1]{\hashfind{#1}} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/common-helpful-programs.tex0000644000175000017500000001774212676175555017274 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Helpful Programs\commonpart]{\label{sec:helpful-programs}% \genidx[\rangebeginlocation]{helpful programs}% Helpful Programs And Libraries\commonpart} Several programs and libraries have proven helpful when working with \App{} or \OtherApp. \section[Raw Image Conversion]{\label{sec:raw-image-conversion}% \genidx{helpful programs!raw image conversion}% Raw Image Conversion} \begin{itemize} \label{app:darktable}% \appidx{Darktable}% \item \uref{\darktableorg}{\application{Darktable}} is an open-source photography workflow application and raw-image developer. \label{prg:dcraw}% \prgidx{dcraw}% \item \uref{\cybercomnetdcraw}{\application{DCRaw}} is a universal raw-converter written by \propername{David Coffin}. \label{app:rawtherapee}% \appidx{RawTherapee}% \item \uref{\rawtherapeecom}{\application{RawTherapee}} is powerful open-source raw converter for Win\asterisk, \mbox{\acronym{MacOS}} and Linux. \label{app:ufraw}% \appidx{UFRaw}% \prgidx{ufraw}% \prgidx{ufraw-batch}% \item \uref{\ufrawsourceforgenet}{\application{UFRaw}} is a raw-converter written by \propername{Udi Fuchs} and based on \application{DCRaw} (see above). It adds a \acronym{GUI} (\command{ufraw}), versatile batch processing (\command{ufraw-batch}), and some additional features such as cropping, noise reduction with wavelets, and automatic lens-error correction. \end{itemize} \section[Image Alignment and Rendering]{\label{sec:image-alignment-and-rendering}% \genidx{helpful programs!image alignment}% \genidx{helpful programs!image rendering}% Image Alignment and Rendering} \begin{itemize} \label{app:hugin}% \appidx{Hugin}% \prgidx{nona \textrm{(Hugin)}}% \prgidx{fulla \textrm{(Hugin)}}% \item \uref{\huginsourceforgenet}{\application{Hugin}} is a \acronym{GUI} that aligns and stitches images. It comes with several command-line tools, like for example \command{nona} to stitch panorama images, \command{align\_image\_stack}\prgidx{align\_image\_stack \textrm{(Hugin)}} to align overlapping images for \acronym{HDR} or create focus stacks, and \command{fulla} to correct lens errors. \label{app:panotools}% \appidx{PanoTools}% \prgidx{PTOptimizer \textrm{(PanoTools)}}% \prgidx{PTmender \textrm{(PanoTools)}}% \item \uref{\panotoolssourceforgenet}{PanoTools} the successor of \propername{Helmut Dersch's} \uref{\homepagehelmutdersch}{original PanoTools} offers a set of command-line driven applications to create panoramas. Most notable are \application{PTOptimizer} for control point optimization and \application{PTmender}, an image stitcher. \end{itemize} \section[Image Manipulation]{\label{sec:image-manipulation}% \genidx{helpful programs!image manipulation}% Image Manipulation} \begin{itemize} \label{app:cinepaint}% \appidx{CinePaint}% \item \uref{\cinepaintorg}{\application{CinePaint}} is a branch of an early \application{Gimp} forked off at version~1.0.4. It sports much less features than the current \application{Gimp}, but offers 8~bit, 16~bit and~32~bit color channels, \acronym{HDR} (for example floating-point \acronym{TIFF}, and \acronym{OpenEXR}), and a tightly integrated color management system. \label{app:gimp}% \appidx{Gimp}% \item \uref{\gimporg}{\application{The Gimp}} is a general purpose image manipulation program. At the time of this writing it is still limited to images with only 8~bits per channel. \label{app:gmic}% \prgidx{gmic}% \item \uref{\gmicsourceforgenet}{\application{G'Mic}} is an open and full-featured framework for image processing, providing several different user interfaces to convert, manipulate, filter, and visualize generic image datasets. \label{app:imagemagick}% \label{app:graphicsmagick}% \appidx{ImageMagick}% \appidx{GraphicsMagick}% \prgidx{convert \textrm{(ImageMagick)}}% \prgidx{display \textrm{(ImageMagick)}}% \prgidx{identify \textrm{(ImageMagick)}}% \prgidx{montage \textrm{(ImageMagick)}}% \prgidx{gm \textrm{(GraphicsMagick)}}% \item Both \uref{\imagemagickorg}{\application{ImageMagick}} and \uref{\graphicsmagickorg}{\application{GraphicsMagick}} are general\hyp purpose command\hyp line controlled image\hyp manipulation programs, for example, \command{convert}, \command{display}, \command{identify}, and \command{montage}. \application{GraphicsMagick} bundles most \application{ImageMagick} invocations in the single dispatcher call to \command{gm}. \end{itemize} \section[High Dynamic Range]{\label{sec:high-dynamic-range}% \genidx{helpful programs!High Dynamic Range}% \genidx{helpful programs!\acronym{HDR}}% High Dynamic Range} \begin{itemize} \label{lib:openexr}% \genidx{OpenEXR@\acronym{OpenEXR}}% \genidx{EXR@\acronym{EXR}}% \genidx{HDR@\acronym{HDR}}% \prgidx{exrdisplay \textrm{(OpenEXR)}}% \item \uref{\openexrcom}{OpenEXR} offers libraries and some programs to work with the \acronym{EXR} \acronym{HDR}-format, for example the \acronym{EXR} display utility \command{exrdisplay}. \label{app:psftools}% \prgidx{PFSTools}% \item \uref{\pfstoolssourceforgenet}{PFSTools} read, write, modify, and tonemap high-dynamic range (\acronym{HDR}) images. \end{itemize} \section[Libraries]{\label{sec:helpful-libraries}% \genidx{helpful programs!libraries}% \genidx{helpful libraries}% Major Libraries} \begin{itemize} \label{lib:jpeg}% \genidx{LibJPEG}% \genidx{JPEG@\acronym{JPEG}}% \gensee{JFIF@\acronym{JFIF}}{\acronym{JPEG}}% \item \uref{\ijgorg}{LibJPEG} is a library for handling the \acronym{JPEG} (\acronym{JFIF}) image format. \label{lib:png}% \genidx{LibPNG}% \genidx{PNG@\acronym{PNG}}% \item \uref{\libpngorg}{LibPNG} is a library that handles the Portable Network Graphics (\acronym{PNG}) image format. \label{lib:tiff}% \genidx{LibTiff}% \genidx{TIFF@\acronym{TIFF}}% \prgidx{tiffinfo \textrm{(libtiff)}}% \item \uref{\remotesensingorglibtiff}{LibTIFF} offers a library and utility programs to manipulate the ubiquitous Tagged Image File Format, \acronym{TIFF}. The nifty \command{tiffinfo} command in the LibTIFF distribution quickly inquires the most important properties of \acronym{TIFF} files. \end{itemize} \section[Meta-Data Handling]{\label{sec:meta-data-handling}% \genidx{helpful programs!meta-data handling}% Meta-Data Handling} \begin{itemize} \label{app:exiftool}% \prgidx{exiftool}% \genidx{EXIF@\acronym{EXIF}}% \item \uref{\snophyqueensucaexiftool}{EXIFTool} reads and writes \acronym{EXIF} meta-data. In particular it copies meta-data from one image to another. \label{app:littlecms}% \appidx{LittleCMS}% \prgidx{tificc \textrm{(LittleCMS)}}% \genidx{ICC@\acronym{ICC}}% \item \uref{\littlecmscom}{LittleCMS} is the color-management library used by \application{Hugin}, \application{DCRaw}, \application{UFRaw}, \App, and \OtherApp. It supplies some binaries, too. \command{tificc}, an \acronym{ICC} color profile applier, is of particular interest. \end{itemize} \section[Camera Firmware Extension]{\label{sec:camera-firmware-extension}% \genidx{helpful programs!camera firmware}% Camera Firmware Extension} \begin{itemize} \label{app:magiclantern}% \appidx{Magic Lantern}% \item \uref{\magiclanternfm}{Magic Lantern} is a software add-on that runs from the \acronym{SD}~(Secure Digital) or \acronym{CF}~(Compact Flash) card and adds new features to cameras of a certain Japanese brand of cameras as for example \begin{itemize} \genidx{dual-ISO@dual-\acronym{ISO}}% \item Dual-\acronym{ISO} (more precisely: simultaneous dual sensor speed); this operation mode may in fact obviate the need for \application{Enfuse}. \item Focus stacking \genidx{bracketing!HDR@\acronym{HDR}}% \gensee{HDR bracketing@\acronym{HDR}-bracketing}{bracketing, \acronym{HDR}}% \item \acronym{HDR}-bracketing \end{itemize} \end{itemize} \genidx[\rangeendlocation]{helpful programs} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/common-authors.tex0000644000175000017500000000356612667236617015466 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Authors\commonpart]{\label{sec:authors}\genidx{authors}Authors\commonpart} \propername{Andrew Mihal} (\mailto{acmihal@users.sourceforge.net}) has written \application{Enblend} and \application{Enfuse}. \bigskip \noindent \strong{Contributors} (in alphabetical order) \begin{itemize} \item \propername{Pablo d'Angelo} (\mailto{dangelo@users.sourceforge.net}) added the contrast criteria. \item \propername{Joe Beda}: \propername{Win32} porting up to version~3.2. \item \propername{Kornel Benko}, \mailto{kornelbenko@users.sourceforge.net}: \application{CMake} support for version~4.0. \item \propername{Roger Goodman}: Proofreading of the manuals. \item \propername{Miko\l{}aj Leszczy\'nski}, \mailto{rosomack@users.sourceforge.net}: GraphCut algorithm in \application{Enblend}. \item \propername{Max Lyons}. \item \propername{Mark} aka `mjz': \propername{Win32} porting up to version~3.2. \item \propername{Thomas Modes}, \mailto{tmodes@users.sourceforge.net}: continuous \propername{Win32} porting and permanent \application{CMake} support. \item \propername{Ryan Sleevi}, \mailto{ryansleevi@users.sourceforge.net}: \propername{Win32} porting of version~4.0. \item \propername{Christoph Spiel} (\mailto{cspiel@users.sourceforge.net}) added the gray projectors, the \acronym{LoG}-based edge detection, an $O(n)$-algorithm for the calculation of local contrast, entropy weighting, and various other features. \item \propername{Brent Townshend}, \mailto{btownshend@users.sourceforge.net}: \acronym{HDR} support. \end{itemize} Thanks to \propername{Simon Andriot} and \propername{Pablo Joubert} for suggesting the \propername{Mertens}-\propername{Kautz}-\propername{Van Reeth} technique and the name ``Enfuse''. %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enfuse-image-requirements.tex0000644000175000017500000000253112667236617017570 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Image Requirements]{\label{sec:image-requirements}% \genidx{requirements!image}% \gensee{image requirements}{requirements, image}% Input Image Requirements} All input images for \App{} must comply with the following requirements. \begin{itemize} \item The images overlap. \item The images agree on their number of bits-per-channel, i.e., their ``depth'': \begin{itemize} \item \code{uint8}, \item \code{uint16}, \item \code{float}, \item etc. \end{itemize} See option~\option{--depth} below for an explanation of different (output) depths. \item \App{} understands the images' filename extensions as well as their file formats. You can check the supported extensions and formats by calling \App{} with option~\option{--show-image-formats}. \end{itemize} Moreover, there are some good practices, which are not enforced by the application, but almost certainly deliver superior results. \begin{itemize} \item Either all files lack an \acronym{ICC} profile, or all images are supplied with the \emph{same} \acronym{ICC} profile. \item If the images' meta-data contains resolution information (``\acronym{DPI}''), it is the same for all pictures. \end{itemize} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/url-def.tex0000644000175000017500000001313312676175555014043 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. %% Superficially check the state of the URLs with wget(1): %% wget --spider --no-verbose --tries=1 --timeout=30 --output-file=url-state.log --input-file=`tr '~' '\0376' < url-def.tex | detex -l | tr '\0376' '~' | sed --expression='/^$/d'` & %% tail --follow url-state.log \urldef{\awaresystemsbeextrasamples}{\url}{http://www.awaresystems.be/imaging/tiff/tifftags/extrasamples.html} \urldef{\brucelindbloomworkingspaceinfo}{\url}{http://www.brucelindbloom.com/index.html?WorkingSpaceInfo.html} \urldef{\cambridgeincolourcomunsharpmask}{\url}{http://www.cambridgeincolour.com/tutorials/unsharp-mask.htm} \urldef{\cilkplusorg}{\url}{https://www.cilkplus.org/} \urldef{\cinepaintorg}{\url}{http://www.cinepaint.org/} \urldef{\clangllvm}{\url}{http://clang.llvm.org/} \urldef{\cybercomnetdcraw}{\url}{http://www.cybercom.net/~dcoffin/dcraw/} \urldef{\darktableorg}{\url}{http://www.darktable.org/} \urldef{\debevecorg}{\url}{http://www.pauldebevec.com/} \urldef{\enblendhgcodesfnet}{\url}{http://hg.code.sf.net/p/enblend/code} \urldef{\enblendsourceforgenet}{\url}{http://enblend.sourceforge.net/} \urldef{\ericbrasseurgamma}{\url}{http://www.4p8.com/eric.brasseur/gamma.html} \urldef{\gccgnuorg}{\url}{https://gcc.gnu.org/} \urldef{\gimpguruorgblendingexposures}{\url}{https://www.gimp.org/tutorials/Blending_Exposures/} \urldef{\gimporg}{\url}{http://www.gimp.org/} \urldef{\gimpsavvy}{\url}{http://gimp-savvy.com/BOOK/index.html?node42.html} \urldef{\gmicsourceforgenet}{\url}{http://gmic.sourceforge.net/} \urldef{\gnuorgcopyleft}{\url}{http://www.gnu.org/copyleft/} \urldef{\gnuorgoctave}{\url}{http://www.gnu.org/software/octave/} \urldef{\graphicsmagickorg}{\url}{http://www.graphicsmagick.org/} \urldef{\hciiwrvigracommonfilters}{\url}{https://ukoethe.github.io/vigra/doc-release/vigra/group__ConvolutionFilters.html} \urldef{\hciiwrvigra}{\url}{https://ukoethe.github.io/vigra/} \urldef{\hipriilog}{\url}{http://homepages.inf.ed.ac.uk/rbf/HIPR2/log.htm} \urldef{\homepagehelmutdersch}{\url}{http://webuser.fh-furtwangen.de/~dersch/} \urldef{\huginsourceforgenet}{\url}{http://hugin.sourceforge.net/} \urldef{\ijgorg}{\url}{http://www.ijg.org/} \urldef{\imagefuser}{\url}{http://imagefuser.sourceforge.net/onlinemanual/} \urldef{\imagemagickorgcommandlineprocessinginput}{\url}{https://www.imagemagick.org/script/command-line-processing.php#input} \urldef{\imagemagickorgusagechannelstrans}{\url}{https://www.imagemagick.org/Usage/transform/} \urldef{\imagemagickorgusagefileshistogram}{\url}{https://www.imagemagick.org/Usage/files/#histogram} \urldef{\imagemagickorg}{\url}{https://www.imagemagick.org/script/index.php} \urldef{\kernelorgglob}{\url}{http://man7.org/linux/man-pages/man7/glob.7.html} \urldef{\khronosorgopencl}{\url}{https://www.khronos.org/opencl/} \urldef{\launchpadnet}{\url}{https://launchpad.net/} \urldef{\libpngorg}{\url}{http://www.libpng.org/pub/png/libpng.html} \urldef{\littlecmscom}{\url}{http://www.littlecms.com/} \urldef{\llvm}{\url}{http://llvm.org/} \urldef{\luminouslandscapebokeh}{\url}{https://luminous-landscape.com/bokeh/} \urldef{\luminouslandscapedigitalblending}{\url}{https://luminous-landscape.com/digital-blending/} \urldef{\luminouslandscaperawfiles}{\url}{https://luminous-landscape.com/understanding-raw-files-explained/} \urldef{\magiclanternfm}{\url}{http://www.magiclantern.fm/index.html} \urldef{\mercurialseleniccom}{\url}{https://www.mercurial-scm.org/} \urldef{\openexrcomfeatures}{\url}{http://www.openexr.com/about.html#features} \urldef{\openexrcom}{\url}{http://www.openexr.com/} \urldef{\openmporg}{\url}{http://openmp.org/wp/} \urldef{\panotoolssourceforgenet}{\url}{http://panotools.sourceforge.net/} \urldef{\pfstoolssourceforgenet}{\url}{http://pfstools.sourceforge.net/} \urldef{\rawtherapeecom}{\url}{http://www.rawtherapee.com/} \urldef{\remotesensingorglibtiff}{\url}{http://www.remotesensing.org/libtiff/} \urldef{\snophyqueensucaexiftool}{\url}{http://www.sno.phy.queensu.ca/~phil/exiftool/} \urldef{\sourceforgenet}{\url}{http://sourceforge.net/} \urldef{\stargatewikiathetomb}{\url}{http://stargate.wikia.com/wiki/The_Tomb} \urldef{\ufrawsourceforgenet}{\url}{http://ufraw.sourceforge.net/} \urldef{\wikipediabornvonkarman}{\url}{https://en.wikipedia.org/wiki/Born-von_Karman_boundary_condition} \urldef{\wikipediaciecam}{\url}{https://en.wikipedia.org/wiki/CIECAM02} \urldef{\wikipediacieluvcolorspace}{\url}{https://en.wikipedia.org/wiki/CIELUV_color_space} \urldef{\wikipediadiffunifiedformat}{\url}{https://en.wikipedia.org/wiki/Diff#Unified_format} \urldef{\wikipediadijkstraalgorithm}{\url}{https://en.wikipedia.org/wiki/Dijkstra_algorithm} \urldef{\wikipediadistancetransform}{\url}{https://en.wikipedia.org/wiki/Distance_transform} \urldef{\wikipediaebnf}{\url}{https://en.wikipedia.org/wiki/Ebnf} \urldef{\wikipediagraphcuts}{\url}{https://en.wikipedia.org/wiki/Graph_cuts_in_computer_vision} \urldef{\wikipediahslandhsv}{\url}{https://en.wikipedia.org/wiki/HSL_and_HSV} \urldef{\wikipediaiccprofile}{\url}{https://en.wikipedia.org/wiki/ICC_profile} \urldef{\wikipediainformationentropy}{\url}{https://en.wikipedia.org/wiki/Information_entropy} \urldef{\wikipedialabcolorspace}{\url}{https://en.wikipedia.org/wiki/Lab_color_space} \urldef{\wikipediaparallax}{\url}{https://en.wikipedia.org/wiki/Parallax} \urldef{\wikipediasimulatedannealing}{\url}{https://en.wikipedia.org/wiki/Simulated_annealing} \urldef{\wikipediastandardilluminant}{\url}{https://en.wikipedia.org/wiki/Standard_illuminant} \urldef{\wikipediaziggaurat}{\url}{https://en.wikipedia.org/wiki/Ziggaurat} %%% Local Variables: %%% fill-column: 96 %%% mode: latex %%% End: enblend-enfuse-4.2/doc/common-common-options.tex0000644000175000017500000002343512676423754016757 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \subsection[Common Options\commonpart]{\label{sec:common-options}% \genidx[\rangebeginlocation]{common options}% \genidx{options!common}% Common Options\commonpart} Common options control some overall features of \App. They are called ``common'' because they are used most often. However, in fact, \App{} and \OtherApp{} do have these options in common. \begin{codelist} \label{opt:compression}% \optidx[\defininglocation]{--compression}% \genidx{output!file compression}% \genidx{compression}% \item[--compression=\metavar{COMPRESSION}]\itemend Write a compressed output file. The default is not to compress the output image. Depending on the output file format, \App{} accepts different values for \metavar{COMPRESSION}. \begin{description} \genidx{compression!\acronym{JPEG}}% \gensee{JPEG@\acronym{JPEG} compression}{compression}% \item[\acronym{JPEG} format.]\itemend The compression either is a literal integer or a keyword\hyp{}option combination. \begin{codelist} \gensee{JPEG@\acronym{JPEG} quality level}{compression}% \item[\metavar{LEVEL}]\itemend Set \acronym{JPEG} quality~\metavar{LEVEL}, where \metavar{LEVEL} is an integer that ranges from 0--100. \item[jpeg\optional{:\metavar{LEVEL}}]\itemend Same as above; without the optional argument just switch on standard \acronym{JPEG} compression. \genidx{compression!arithmetic \acronym{JPEG}}% \gensee{arithmetic \acronym{JPEG} compression}{compression}% \item[jpeg-arith\optional{:\metavar{LEVEL}}]\itemend Switch on arithmetic \acronym{JPEG} compression. With optional argument set the arithmetic compression~\metavar{LEVEL}, where \metavar{LEVEL} is an integer that ranges from 0--100. \end{codelist} \item[\acronym{TIF} format.]\itemend Here, \metavar{COMPRESSION} is one of the keywords: \begin{codelist} \item[none]\itemend Do not compress. This is the default. \genidx{compression!deflate}% \gensee{deflate compression}{compression}% \item[deflate]\itemend Use the \propername{Deflate} compression scheme also called \acronym{ZIP}-in-\acronym{TIFF}. \propername{Deflate} is a lossless data compression algorithm that uses a combination of the \acronym{LZ77} algorithm and \propername{Huffman} coding. \genidx{compression!\acronym{JPEG} of \acronym{TIFF}}% \item[jpeg\optional{:\metavar{LEVEL}}]\itemend Use \acronym{JPEG} compression. With optional argument set the compression~\metavar{LEVEL}, where \metavar{LEVEL} is an integer that ranges from 0--100. \genidx{compression!\acronym{LZW}}% \gensee{LZW@\acronym{LZW} compression}{compression}% \item[lzw]\itemend Use \propername{Lempel}-\propername{Ziv}-\propername{Welch} (\acronym{LZW}) adaptive compression scheme. \acronym{LZW} compression is lossless. \genidx{compression!packbits}% \gensee{packbits compression}{compression}% \item[packbits]\itemend Use \propername{PackBits} compression scheme. \propername{PackBits} is a particular variant of run-length compression; it is lossless. \end{codelist} \item[Any other format.]\itemend Other formats do not accept a \metavar{COMPRESSION} setting. However, the underlying \uref{\hciiwrvigra}{\acronym{VIGRA}} library automatically compresses \filename{png}-files with the \propername{Deflate} method. (\acronym{VIGRA} is the image manipulation library upon which \App{} is based.) \end{description} %% -- Commented out for Stable Branch 4.2 %% \label{opt:gpu}% %% \optidx[\defininglocation]{--gpu}% %% \genidx{graphics processing unit}% %% \gensee{GPU@\acronym{GPU}}{graphics processing unit}% %% \genidx{central processing unit}% %% \gensee{CPU@\acronym{CPU}}{central processing unit}% %% \genidx{OpenCL@\acronym{OpenCL}}% %% \item[--gpu \restrictednote{\acronym{OpenCL}-enabled versions %% only.}]\itemend %% Employ one of the graphics processing units (\acronym{GPU}s) to perform computing instead of %% the central processing units (\acronym{CPU}s) alone. \App{} must have been compiled with %% support for \acronym{OpenCL} access to the \acronym{GPU} for this feature. %% %% Depending on the input images, the options passed to \App{}, and the relative performance of %% the \acronym{CPU}s to the \acronym{GPU}s this option may or may not increase performance. %% %% This option enables \acronym{GPU} processing on the selected \acronym{GPU}s. To choose a %% particular \acronym{GPU} or override \App's default choice use %% option~\flexipageref{\option{--pre\shyp fer\hyp gpu}}{opt:prefer-gpu}. %% %% Negate this option with \sample{--no-gpu}\optidx[\defininglocation]{--no-gpu}. \label{opt:levels}% \optidx[\defininglocation]{--levels}% \shoptidx{-l}{--levels}% \genidx{levels!pyramid}% \gensee{pyramid levels}{levels, pyramid}% \item[\itempar{-l \metavar{LEVELS} \\ --levels=\metavar{LEVELS}}]\itemend Use at most this many \metavar{LEVELS} for pyramid\footnotemark{} blending if \metavar{LEVELS} is positive, or reduce the maximum number of levels used by $-\metavar{LEVELS}$ if \metavar{LEVELS} is negative; \sample{auto} or \sample{automatic} restore the default, which is to use the maximum possible number of levels for each overlapping region. \footnotetext{As \genidx{Jackson, Daniel@\propername{Jackson, Daniel}}\propername{Dr.~Daniel Jackson} correctly \ahref{\stargatewikiathetomb}{noted}, actually, it is not a pyramid: ``Ziggaurat, it's a \ahref{\wikipediaziggaurat}{Ziggaurat}.''}% FIXME The number of levels used in a pyramid controls the balance between local and global image features (contrast, saturation,~\dots) in the blended region. Fewer levels emphasize local features and suppress global ones. The more levels a pyramid has, the more global features will be taken into account. \begin{geeknote} As a guideline, remember that each new level works on a linear scale twice as large as the previous one. So, the zeroth layer, the original image, obviously defines the image at single-pixel scale, the first level works at two-pixel scale, and generally, the $n^{\mathrm th}$ level contains image data at $2^n$-pixel scale. This is the reason why an image of $\mbox{width} \times \mbox{height}$~pixels cannot be deconstructed into a pyramid of more than \[ \lfloor \log_2(\min(\mbox{width}, \mbox{height})) \rfloor\quad\mbox{levels.} \] If too few levels are used, ``halos'' around regions of strong local feature variation can show up. On the other hand, if too many levels are used, the image might contain too much global features. Usually, the latter is not a problem, but is highly desired. This is the reason, why the default is to use as many levels as is possible given the size of the overlap regions. \App{} may still use a smaller number of levels if the geometry of the overlap region demands. \end{geeknote} Positive values of \metavar{LEVELS} limit the maximum number of pyramid levels. Depending on the size and geometry of the overlap regions this may or may not influence any pyramid. Negative values of \metavar{LEVELS} reduce the number of pyramid levels below the maximum no matter what the actual maximum is and thus always influence all pyramids. Use \sample{auto} or \sample{automatic} as \metavar{LEVELS} to restore the automatic calculation of the maximum number of levels. The valid range of the absolute value of \metavar{LEVELS} is \val{val:minimum-pyramid-levels} to \val{val:maximum-pyramid-levels}. \label{opt:output}% \optidx[\defininglocation]{--output}% \shoptidx{-o}{--output}% \genidx{filename!output}% \gensee{output filename}{filename, output}% \gensee{output filename!default}{filename, output, default}% \genidx{filename!output!default}% \gensee{default output filename}{filename, output, default}% \item[\itempar{-o \metavar{FILE} \\ --output=\metavar{FILE}}]\itemend Place \appdid{} output image in \metavar{FILE}. If \sample{--output} is omitted, \App{} writes the resulting image to \filename{\val{val:default-output-filename}}. \label{opt:verbose}% \optidx[\defininglocation]{--verbose}% \shoptidx{-v}{--verbose}% \genidx{level!verbosity}% \gensee{verbosity level}{level, verbosity}% \item[\itempar{-v \optional{\metavar{LEVEL}} \\ --verbose\optional{=\metavar{LEVEL}}}]\itemend Without an argument, increase the verbosity of progress reporting. Giving more \option{--verbose}~options will make \App{} more verbose; see \sectionName~\fullref{sec:finding-out-details} for an exemplary output. Directly set a verbosity level with a non-negative integral~\metavar{LEVEL}. \tableName~\ref{tab:verbosity-levels} shows the messages available at a particular \metavar{LEVEL}. \begin{table} \centering \begin{tabular}{cp{.75\linewidth}} \hline \multicolumn{1}{c|}{Level} & \multicolumn{1}{c}{Messages} \\ \hline\extraheadingsep 0 & only warnings and errors \\ 1 & reading and writing of images \\ 2 & mask generation, pyramid, and blending \\ 3 & reading of response files, color conversions \\ 4 & image sizes, bounding boxes and intersection sizes \\ 5 & \restrictednote{\application{Enblend} only.} detailed information on the optimizer runs \\ 6 & estimations of required memory in selected processing steps \\ \end{tabular} \caption[Verbosity levels]{\label{tab:verbosity-levels}Verbosity levels of \app{}; each level includes all messages of the lower levels.} \end{table} The default verbosity level of \App{} is \val{val:default-verbosity-level}. \end{codelist} \genidx[\rangeendlocation]{common options} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/uml-dot.m40000644000175000017500000000734112566033015013570 00000000000000m4_dnl This file is part of Enblend. m4_dnl Licence details can be found in the file COPYING. m4_dnl Definitions for a common structure and appearance of all m4_dnl flow charts. m4_dnl m4_dnl Despite the name of the file and the prefix of all macros m4_dnl (`uml_'), we treat only `Activity Diagrams' here for we do not m4_dnl need more for the Enblend/Enfuse documentation. m4_define(`uml_font', `Helvetica') m4_dnl Graph Attributes m4_define(`uml_graph_font', `uml_font') m4_define(`uml_graph_font_size', `10') m4_define(`uml_activity_graph', `fontname = uml_graph_font, fontsize = uml_graph_font_size, forcelabels = true, splines = ortho') m4_dnl _Sometimes we want to fit a larger graph to a printed page. m4_dnl This macro helps while leaving other formats than EPS anone. m4_define(`uml_compressed_layout', m4_ifdef(`dot_output_type', m4_ifelse(dot_output_type, `eps', `ranksep = 0.375, ratio = compress'))) m4_dnl Attributes of the `Start' and `Finish' terminal symbols m4_define(`uml_terminal_color', `black') m4_define(`uml_terminal_size', `0.125') m4_define(`uml_start', `fillcolor = uml_terminal_color, fixedsize = shape, label = "", shape = circle, style = filled, width = uml_terminal_size') m4_define(`uml_finish', `fillcolor = uml_terminal_color, fixedsize = shape, label = "", shape = doublecircle, style = filled, width = uml_terminal_size') m4_dnl Shape of Activity boxes and the edges that connect them m4_define(`uml_activity_font', `uml_font') m4_define(`uml_activity_font_size', `9') m4_define(`uml_activity_penwidth', `0.5') m4_define(`uml_arrow_size', `0.667') m4_define(`uml_edge_font_size', `8') m4_define(`uml_activity', `fontname = uml_activity_font, fontsize = uml_activity_font_size, penwidth = uml_activity_penwidth, shape = box, style = rounded') m4_define(`uml_edge', `arrowsize = uml_arrow_size, fontname = uml_activity_font, fontsize = uml_edge_font_size, penwidth = uml_activity_penwidth') m4_dnl Shape of Notes and the edges that connect Activity boxes and Notes m4_define(`uml_note_color', `"0.167,0.4,1.0"') # RGB: 0xffff99, "pale yellow" m4_define(`uml_note_font', `uml_font') m4_define(`uml_note_font_size', `9') m4_define(`uml_note_penwidth', `0.35') m4_define(`uml_note', `fillcolor = uml_note_color, fontname = uml_note_font, fontsize = uml_note_font_size, penwidth = uml_note_penwidth, shape = note, style = filled') m4_define(`uml_note_edge', `dir = none, fontname = uml_note_font, fontsize = uml_edge_font_size, penwidth = uml_note_penwidth, style = dashed') m4_dnl Shape and contents of Branch/Merge conditionals m4_define(`uml_conditional_height', `0.25') m4_define(`uml_conditional_width', `0.5') m4_define(`uml_branch', `fixedsize = shape, height = uml_conditional_height, label = "", shape = diamond, style = solid, width = uml_conditional_width') m4_define(`uml_merge', `uml_branch') m4_dnl Shape and contents of Join/Fork parallelism symbols m4_define(`uml_parallelism_height', `0.02') m4_define(`uml_parallelism_width', `2') m4_define(`uml_fork', `color = black, fixedsize = shape, height = uml_parallelism_height, label = "", shape = box, style = filled, width = uml_parallelism_width') m4_define(`uml_join', `uml_fork') enblend-enfuse-4.2/doc/exposure-weights.gp0000644000175000017500000000311412566032753015621 00000000000000default_optimum = 0.5 default_width = 0.2 fwhm_gaussian = 2.3548200450309493820231386529193992755 fwhm_lorentzian = 2.8284271247461900976033774484193961571 fwhm_halfsinusodial = 2.0943951023931954923084289221863352561 fwhm_fullsinusodial = pi fwhm_power = 1.6817928305074290860622509524664297901 gaussian(y, y_opt, width) = exp(-0.5 * ((y - y_opt) / width)**2) lorentzian(y, y_opt, width) = 1.0 / (1.0 + ((y - y_opt) / (width * fwhm_gaussian / fwhm_lorentzian))**2 / 2.0) halfsine(y, y_opt, width) = \ abs((y - y_opt) / (width * fwhm_gaussian / fwhm_halfsinusodial)) <= pi / 2.0 ? \ cos((y - y_opt) / (width * fwhm_gaussian / fwhm_halfsinusodial)) : \ 0 fullsine(y, y_opt, width) = \ abs((y - y_opt) / (width * fwhm_gaussian / fwhm_fullsinusodial)) <= pi ? \ (1.0 + cos((y - y_opt) / (width * fwhm_gaussian / fwhm_fullsinusodial))) / 2.0 : \ 0 power(y, y_opt, width) = \ abs((y - y_opt) / (width * fwhm_gaussian / fwhm_power)) <= 1.0 ? \ 1.0 - (abs(y - y_opt) / (width * fwhm_gaussian / fwhm_power))**4 : \ 0.0 set grid ytics set key bmargin center horizontal set samples 1023 set xlabel "$Y$" set xtics 0.2 set ylabel "$w$" set ytics 0.5 load DATA_DIR . "/colors.gp" plot [y = 0:1] \ gaussian(y, default_optimum, default_width) title "Gaussian", \ lorentzian(y, default_optimum, default_width) title "Lorentzian", \ halfsine(y, default_optimum, default_width) title "Half-Sine", \ fullsine(y, default_optimum, default_width) title "Full-Sine", \ power(y, default_optimum, default_width) title "Bi-Square" enblend-enfuse-4.2/doc/enblend-seam-generators.tex0000644000175000017500000001010512676175561017177 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Seam Generators]{\label{sec:seam-generators}% \genidx[\rangebeginlocation]{seam generation}% Seam Generators} This version of \App{} supports two main algorithms to generate seam lines. Use option~\option{--primary-seam-generator}=\metavar{ALGORITHM} to select one of the generators. \begin{description} \genidx[\summarylocation]{seam generation}% \genidx{nearest feature transform}% \gensee{NFT@\acronym{NFT}}{nearest feature transform}% \genidx{Alsuwaiyel, Muhammad@\propername{Alsuwaiyel, Muhammad H.}}% \genidx{Gavrilova, Marina@\propername{Gavrilova, Marina}}% \genidx{distance transform}% \gensee{DT@\acronym{DT}}{distance transform}% \item[Nearest Feature Transform (\acronym{NFT})]% \itemx[\metavar{ALGORITHM}=\code{nearest-feature-transform}]\itemend The Nearest Feature Transform\footnotemark{}, also known as \uref{\wikipediadistancetransform}{Distance Transform} (\acronym{DT}), is a fast and efficient technique to produce a seam line route given the geometries of multiple overlapping images.% % \footnotetext{\propername{Muhammad H. Alsuwaiyel} and \propername{Marina Gavrilova}, ``On the Distance Transform of Binary Images'', Proceedings of the International Conference on Imaging Science, Systems, and Technology, June 2000, \abbreviation{Vols.}~I and II, pages~83--86.} \acronym{NFT} as implemented in this version of \App{} only takes into account the \emph{shape of the overlap area.} It completely ignore the images' contents. \genidx{graph-cut algorithm}% \gensee{GC@\acronym{GC}}{graph-cut algorithm}% \item[Graph-Cut (\acronym{GC})]% \itemx[\metavar{ALGORITHM}=\code{graph-cut}]\itemend \uref{\wikipediagraphcuts}{Graph-Cut} is a region-oriented way of segmenting images. The generator is based on the idea of finding a minimum cost ``cut'' of a graph created from a given image pair. A ``cut'' is where the seam line appears. \acronym{GC} determines the cost from the overlapping images' contents. \end{description} \genidx{seam generation!details}% The most significant difference between the two algorithms is the output mask gradation. \acronym{NFT} produces a coarse approximation of the seam, running as far away from the overlap-region borders as possible. The resulting mask could then be blended as-is, however, \App{} by default runs image-content dependent optimizers to increase the mask gradation and for example omits the regions where the images differ. The result is a finer seam line, which only loosely follows the shape of \acronym{NFT}'s primary seam. \genidx{graphcut!details}% Graph-Cut, on the other hand, is capable of producing the final mask in one pass without the need of further optimizers. It looks for a seam line that is \emph{globally} optimal, taking into account feature frequency, as well as image dissimilarity. This means, the seam is less likely to cross lines like for example fences, lampposts, or road markings, where they would be visible. The optimizers which run after \acronym{NFT} can also be run after \acronym{GC}. Nevertheless, \acronym{GC} works best just with a fine mask (option~\option{--fine-mask}); optimizers are then automatically \emph{turned off} to take full advantage of the detailed seam \acronym{GC} produces. \acronym{GC} requires more memory and computation time to complete than \acronym{NFT}. Thus, it is best to prefer \acronym{NFT} where the images used are large and execution time is crucial. If quality is the priority, using \acronym{GC} and fine mask usually produces visually more pleasing results. \genidx{graphcut!limitations}% \acronym{GC} is currently limited to seams that begin and end on the images' borders. This means that the algorithm cannot run in cases where, for example, one image is contained in another, resulting in a loop-like seam. In such cases, though, \App{} automatically falls back to a \acronym{NFT}-generated seam, making its application transparent to the user. \genidx[\rangeendlocation]{seam generation} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/common-external-masks.tex0000644000175000017500000000536512676175546016741 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \newcommand*{\multiresolutiontext}{mul\-ti-res\-o\-lu\-tion} \section[External Masks]{\label{sec:external-masks}% \genidx{external mask}% \genidx{mask!external}% External Masks} In the usual workflow \App{} and \OtherApp{} generate the blending and fusing masks according to the command-line options and the input images including their associated alpha-channels, and then they immediately use these masks for \multiresolutiontext{} blending or \multiresolutiontext{} fusing the output image. Sometimes more control over the masks is wanted. To this end, both applications provide the option pair \option{--load-masks} and \option{--save-masks}. See \chapterName~\fullref{sec:invocation}, for detailed explanations of both options. With the help of these options the processing can be broken up into two phases: \begin{enumerate}% \optidx{--save-masks}% \optidx{--output}% \item Save masks with \option{--save-masks}. Generate masks and save them into image files. Avoid option~\option{--output} here unless the blended or fused image at this point is wanted. \optidx{--load-masks}% \item Load possibly modified masks with \option{--load-masks} from files and then blend or fuse the final image with the help of the loaded masks only. Neither application (re-)generates any mask in this phase. The loaded masks completely control the \multiresolutiontext{} blending or \multiresolutiontext{} fusing the output image. \end{enumerate} In between these two steps the user may apply whatever transformation to the mask files, as long as their geometries and offsets remain the same. Thus the ``Combine Images'' box of \figureName~\ref{fig:photographic-workflow} becomes three activities as is depicted in \figureName~\ref{fig:external-mask-workflow}. \begin{figure} \begin{maxipage} \centering \includeimage{external-mask-workflow} \end{maxipage} \caption[External mask workflow]{\label{fig:external-mask-workflow}% \genidx{workflow!external mask}% Workflow for externally modified masks. The ``Blend or Fuse Using Masks'' step utilizes the \multiresolutiontext{} algorithm just as for internal workflow without mask files.} \end{figure} To further optimize this kind of workflow, both \App{} and \OtherApp{} stop after mask generation if option~\option{--save-masks} is given, but \emph{no output file} is specified with the \option{--output} option. This way the time for pyramid generation, blending, fusing, and writing the final image to disk is saved, as well as no output image gets generated. Note that options~\option{--save-masks} and \option{--load-masks} cannot be used simultaneously. %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/fullsine.gp0000644000175000017500000000126712566032753014127 00000000000000default_optimum = 0.5 default_width = 0.2 fwhm_gaussian = 2.3548200450309493820231386529193992755 fwhm_fullsinusodial = pi fullsine(y, y_opt, width) = \ abs((y - y_opt) / (width * fwhm_gaussian / fwhm_fullsinusodial)) <= pi ? \ (1.0 + cos((y - y_opt) / (width * fwhm_gaussian / fwhm_fullsinusodial))) / 2.0 : \ 0 set key bmargin center horizontal set samples 1023 set xlabel "$Y$" set xtics 0.2 set ylabel "$w$" set ytics 0.2 load DATA_DIR . "/colors.gp" plot [y = 0:1] \ fullsine(y, default_optimum, 0.1) title "width = 0.1", \ fullsine(y, default_optimum, 0.2) title "default width = 0.2", \ fullsine(y, default_optimum, 0.4) title "width = 0.4" enblend-enfuse-4.2/doc/common-fdl.tex0000644000175000017500000005030012667236617014532 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[\acronym{GNU} \acronym{FDL}\commonpart]% {\label{sec:fdl}% \genidx{GNU Free Documentation License@\acronym{GNU} Free Documentation License}% \gensee{GNU FDL@\acronym{GNU} \acronym{FDL}}{\acronym{GNU} Free Documentation License}% \gensee{FDL@\acronym{FDL}}{\acronym{GNU} Free Documentation License}% The \acronym{GNU} Free Documentation License\commonpart} Version 1.2, November 2002 \begin{quotation} \noindent Copyright \copyright{} 2000, 2001, 2002 Free Software Foundation, Inc. \\ 51 Franklin St, Fifth Floor, Boston, MA 02110--1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. \end{quotation} \begin{enumerate} \setcounter{enumi}{-1}% FIXME: \setcounter does not work with Hevea. \item PREAMBLE \\ The purpose of this License is to make a manual, textbook, or other functional and useful document free in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. This License is a kind of ``copyleft'', which means that derivative works of the document must themselves be free in the same sense. It complements the \acronym{GNU} General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference. \item APPLICABILITY AND DEFINITIONS \\ This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The ``Document'', below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as ``you''. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law. A ``Modified Version'' of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. A ``Secondary Section'' is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The ``Invariant Sections'' are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none. The ``Cover Texts'' are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5~words, and a Back-Cover Text may be at most 25~words. A ``Transparent'' copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not ``Transparent'' is called ``Opaque''. Examples of suitable formats for Transparent copies include plain \acronym{ascii} without markup, Texinfo input format, \LaTeX{} input format, \acronym{SGML} or \acronym{XML} using a publicly available \acronym{DTD}, and standard-conforming simple \acronym{HTML}, PostScript or \acronym{PDF} designed for human modification. Examples of transparent image formats include \acronym{PNG}, \acronym{XCF} and \acronym{JPG}. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, \acronym{SGML} or \acronym{XML} for which the \acronym{DTD} and/or processing tools are not generally available, and the machine-generated \acronym{HTML}, PostScript or \acronym{PDF} produced by some word processors for output purposes only. The ``Title Page'' means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, ``Title Page'' means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text. A section ``Entitled XYZ'' means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as ``Acknowledgements'', ``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' of such a section when you modify the Document means that it remains a section ``Entitled XYZ'' according to this definition. The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License. \item VERBATIM COPYING \\ You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies. \item COPYING IN QUANTITY \\ If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document. \item MODIFICATIONS \\ You may copy and distribute a Modified Version of the Document under the conditions of sections~2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version: \begin{enumerate} \renewcommand{\labelenumii}{\Alph{enumii}.} \item Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. \item List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement. \item State on the Title page the name of the publisher of the Modified Version, as the publisher. \item Preserve all the copyright notices of the Document. \item Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. \item Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below. \item Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice. \item Include an unaltered copy of this License. \item Preserve the section Entitled ``History'', Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled ``History'' in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence. \item Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the ``History'' section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. \item For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. \item Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. \item Delete any section Entitled ``Endorsements''. Such a section may not be included in the Modified Version. \item Do not retitle any existing section to be Entitled ``Endorsements'' or to conflict in title with any Invariant Section. \item Preserve any Warranty Disclaimers. \end{enumerate} If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles. You may add a section Entitled ``Endorsements'', provided it contains nothing but endorsements of your Modified Version by various parties---for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25~words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. \item COMBINING DOCUMENTS \\ You may combine the Document with other documents released under this License, under the terms defined in section~4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections Entitled ``History'' in the various original documents, forming one section Entitled ``History''; likewise combine any sections Entitled ``Acknowledgements'', and any sections Entitled ``Dedications''. You must delete all sections Entitled ``Endorsements.'' \item COLLECTIONS OF DOCUMENTS \\ You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document. \item AGGREGATION WITH INDEPENDENT WORKS \\ A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an ``aggregate'' if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. If the Cover Text requirement of section~3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate. \item TRANSLATION \\ Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section~4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail. If a section in the Document is Entitled ``Acknowledgements'', ``Dedications'', or ``History'', the requirement (section~4) to Preserve its Title (section~1) will typically require changing the actual title. \item TERMINATION \\ You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. \item FUTURE REVISIONS OF THIS LICENSE \\ The Free Software Foundation may publish new, revised versions of the \acronym{GNU} Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See \uref{\gnuorgcopyleft}{\acronym{GNU} Copyleft}. Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License ``or any later version'' applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. \end{enumerate} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enfuse-fusion-options.tex0000644000175000017500000001262712676175546016773 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \subsection[Fusion Options]{\label{sec:fusion-options}% \genidx[\rangebeginlocation]{fusion options}% \genidx{options!fusion}% Fusion Options} Fusion options define the proportion to which each input image's pixel contributes to the output image. \begin{codelist} \label{opt:contrast-weight}% \optidx[\defininglocation]{--contrast-weight}% \genidx{weight!local contrast}% \gensee{contrast weight}{weight, local contrast}% \gensee{local contrast weight}{weight, local contrast}% \item[--contrast-weight=\metavar{WEIGHT}]\itemend Sets the relative \metavar{WEIGHT} of high local-contrast pixels. Valid range: $\val{val:minimum-weight-contrast} \leq \metavar{WEIGHT} \leq \val{val:maximum-weight-contrast}$, default: \val{val:default-weight-contrast}. See \sectionName~\ref{sec:local-contrast-weighting} and \ref{sec:expert-options}, option~\flexipageref{\option{--contrast-window-size}}{opt:contrast-window-size}. \label{opt:entropy-weight}% \optidx[\defininglocation]{--entropy-weight}% \genidx{weight!entropy}% \gensee{entropy weight}{weight, entropy}% \item[--entropy-weight=\metavar{WEIGHT}]\itemend Sets the relative \metavar{WEIGHT} of high local entropy pixels. Valid range: $\val{val:minimum-weight-entropy} \leq \metavar{WEIGHT} \leq \val{val:maximum-weight-entropy}$, default: \val{val:default-weight-entropy}. See \sectionName~\ref{sec:expert-options} and \ref{sec:local-entropy-weighting}, options~\flexipageref{\option{--entropy-window-size}}{opt:entropy-window-size} and \flexipageref{\option{--entropy-cutoff}}{opt:entropy-cutoff}. \label{opt:exposure-optimum}% \optidx[\defininglocation]{--exposure-optimum}% \genidx{exposure!optimum}% \gensee{optimum exposure}{exposure, optimum}% \item[--exposure-optimum=\metavar{OPTIMUM}]\itemend Determine at what normalized exposure value the \metavar{OPTIMUM} exposure of the input images is. This is, set the position of the maximum of the exposure weight curve. Use this option to fine-tune exposure weighting. Valid range: $\val{val:minimum-exposure-optimum} \leq \metavar{OPTIMUM} \leq \val{val:maximum-exposure-optimum}$, default: \val{val:default-exposure-optimum}. \label{opt:exposure-weight}% \optidx[\defininglocation]{--exposure-weight}% \genidx{exposure!weight}% \gensee{weight!exposure}{exposure, weight}% \item[--exposure-weight=\metavar{WEIGHT}]\itemend Set the relative \metavar{WEIGHT} of the ``well-exposedness'' criterion as defined by the chosen exposure weight function (see option~\flexipageref{\option{--ex\shyp po\shyp sure-weight-func\shyp tion}}{opt:exposure-weight-function} below). Increasing this weight relative to the others will make well-exposed pixels contribute more to the final output. Valid range: $\val{val:minimum-weight-exposure} \leq \metavar{WEIGHT} \leq \val{val:maximum-weight-exposure}$, default: \val{val:default-weight-exposure}. See Section~\fullref{sec:exposure-weighting}. \label{opt:exposure-width}% \optidx[\defininglocation]{--exposure-width}% \genidx{exposure!width}% \gensee{width of exposure weight curve}{exposure, width}% \genidx{FWHM@\acronym{FWHM}}% \item[--exposure-width=\metavar{WIDTH}]\itemend Set the characteristic \metavar{WIDTH} (\acronym{FWHM}) of the exposure weight function. Low numbers give less weight to pixels that are far from the user-defined optimum (option~\flexipageref{\option{--exposure-optimum}}{opt:exposure-optimum}) and vice versa. Use this option to fine-tune exposure weighting (See Section~\fullref{sec:exposure-weighting}). Valid range: $\metavar{WIDTH} > \val{val:minimum-exposure-width}$, default: \val{val:default-exposure-width}. \label{opt:hard-mask}% \optidx[\defininglocation]{--hard-mask}% \genidx{mask!hard}% \gensee{hard mask}{mask, hard}% \item[--hard-mask]\itemend Force hard blend masks on the finest scale. This is the opposite flag of option~\flexipageref{\option{--soft-mask}}{opt:soft-mask}. This blending mode avoids averaging of fine details (only) at the expense of increasing the noise. However it considerably improves the sharpness of focus stacks. Blending with hard masks has only proven useful with focus stacks. See also \sectionName~\ref{sec:fusion-options} and options~\flexipageref{\option{--contrast-weight}}{opt:contrast-weight} as well as \flexipageref{\option{--contrast-window-size}}{opt:contrast-window-size} above. \label{opt:saturation-weight}% \optidx[\defininglocation]{--saturation-weight}% \genidx{saturation weight}% \gensee{weight!saturation}{saturation weight}% \item[--saturation-weight=\metavar{WEIGHT}]\itemend Set the relative \metavar{WEIGHT} of high-saturation pixels. Increasing this weight makes pixels with high saturation contribute more to the final output. Valid range: $\val{val:minimum-weight-saturation} \leq \metavar{WEIGHT} \leq \val{val:maximum-weight-saturation}$, default: \val{val:default-weight-saturation}. Saturation weighting is only defined for color images; see \sectionName~\ref{sec:saturation-weighting}. \label{opt:soft-mask}% \optidx[\defininglocation]{--soft-mask}% \genidx{mask!soft}% \gensee{soft mask}{mask, soft}% \item[--soft-mask]\itemend Consider all masks when fusing. This is the default. \end{codelist} \genidx[\rangeendlocation]{fusion options} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/common-bug-reports.tex0000644000175000017500000001457012676175555016252 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Bug Reports\commonpart]{\label{sec:bug-reports}% \genidx[\rangebeginlocation]{bug!reports}% \gensee{problem reports}{bug reports}% Bug Reports\commonpart} \begin{geeknote} \noindent Most of this appendix was taken from the \uref{\gnuorgoctave}{Octave} documentation. \end{geeknote} Bug reports play an important role in making \App{} and~\OtherApp{} reliable and enjoyable. \genidx{bug!database at LaunchPad}% \gensee{LaunchPad!bug database}{bug, database at LaunchPad}% When you encounter a problem, the first thing to do is to see if it is already known. To this end, visit the package's \uref{\launchpadnet}{LaunchPad} bug \urefval{val:PACKAGE_BUGREPORT}{database}. Search it for your particular problem. If it is not known, please report it. In order for a bug report to serve its purpose, you must include the information that makes it possible to fix the bug. \section[Found a Bug?]{\label{sec:have-you-really-found-a-bug}% \genidx{bug!reports!identification of bugs}% Have You Really Found a Bug?} If you are not sure whether you have found a bug, here are some guidelines: \begin{itemize} \item If \App{} or \OtherApp{} get a fatal signal, for any options or input images, that is a bug. \item If \App{} or \OtherApp{} produce incorrect results, for any input whatever, that is a bug. \item If \App{} or \OtherApp{} produce an error message for valid input, that is a bug. \item If \App{} or \OtherApp{} do not produce an error message for invalid input, that is a bug. \end{itemize} \section[How to Report Bugs]{\label{sec:how-to-report-bugs}% \genidx{bug!reports!how to}% How to Report Bugs} The fundamental principle of reporting bugs usefully is this: report all the facts. If you are not sure whether to state a fact or leave it out, state it. Often people omit facts because they think they know what causes the problem and they conclude that some details do not matter. Play it safe and give a specific, complete example. Keep in mind that the purpose of a bug report is to enable someone to fix the bug if it is not known. Always write your bug reports on the assumption that the bug is not known. Try to make your bug report self-contained. If we have to ask you for more information, it is best if you include all the previous information in your response, as well as the information that was missing. To enable someone to investigate the bug, you should include all these things: \begin{itemize} \item The exact version and configuration of \App. You can get the data by running \app{} with the options \option{--version} and~\option{--verbose} together. See also \sectionName~\fullref{sec:finding-out-details} on how to find out the exact configuration of your binary. \item A complete set of input images that will reproduce the bug. Strive for a minimal set of \emph{small} images, where images up to 1500\classictimes 1000~pixels qualify as small. \item The type of machine you are using, and the operating system name and its version number. \item A complete list of any modifications you have made to the source. Be precise about these changes. Show a delta generated with \command{diff} for them. \item Details of any other deviations from the standard procedure for installing \App{} and \OtherApp{}. \item The \emph{exact command line} you use to call \App{} or \OtherApp{}, which then triggers the bug. Examples: \begin{terminal} \$ \squiggle/local/bin/enblend -v \bslash \\ ~~~~--fine-mask \bslash \\ ~~~~--optimizer-weights=3:2 \bslash \\ ~~~~--mask-vectorize=12.5\% \bslash \\ ~~~~image-1.png image-2.png \end{terminal} or: \begin{terminal} \$ /local/bin/enfuse \bslash \\ ~~~~--verbose \bslash \\ ~~~~--exposure-weight=0 --saturation-weight=0 --entropy-weight=1 \bslash \\ ~~~~--gray-projector=l-star \bslash \\ ~~~~--entropy-cutoff=1.667\% \bslash \\ ~~~~layer-01.ppm layer-02.ppm layer-03.ppm \end{terminal} \appidx{Hugin}% \appidx{ImageFuser}% If you call \App{} or \OtherApp{} from within a \acronym{GUI} like, for example, \uref{\huginsourceforgenet}{Hugin} or \uref{\imagefuser}{ImageFuser} by \propername{Harry van der Wolf}, copy\&paste or write down the command line that launches \App{} or \OtherApp{}. \item A description of what behavior you observe that you believe is incorrect. For example, ``The application gets a fatal signal,'' or, ``The output image contains black holes.'' Of course, if the bug is that the application gets a fatal signal, then one cannot miss it. But if the bug is incorrect output, we might not notice unless it is glaringly wrong. \end{itemize} \section[Sending Patches]{\label{sec:sending-patches}% \genidx{bug!reports!sending patches}% Sending Patches for \App{} or \OtherApp{}} If you would like to write bug fixes or improvements for \App{} or \OtherApp{}, that is very helpful. When you send your changes, please follow these guidelines to avoid causing extra work for us in studying the patches. If you do not follow these guidelines, your information might still be useful, but using it will take extra work. \begin{itemize} \item Send an explanation with your changes of what problem they fix or what improvement they bring about. For a bug fix, just include a copy of the bug report, and explain why the change fixes the bug. \item Always include a proper bug report for the problem you think you have fixed. We need to convince ourselves that the change is right before installing it. Even if it is right, we might have trouble judging it if we do not have a way to reproduce the problem. \item Include all the comments that are appropriate to help people reading the source in the future understand why this change was needed. \item Do not mix together changes made for different reasons. Send them individually. If you make two changes for separate reasons, then we might not want to install them both. We might want to install just one. \item Use the version control system to make your diffs. Prefer the \uref{\wikipediadiffunifiedformat}{unified diff} format: \code{hg diff --unified 4}. \item You can increase the probability that your patch gets applied by basing it on a recent revision of the sources. \end{itemize} \genidx[\rangeendlocation]{bug!reports} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enblend-expert-mask-generation-options.tex0000644000175000017500000003117512676175561022177 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \subsection[Expert Mask Generation Options]{\label{sec:expert-mask-generation-options}% \genidx[\rangebeginlocation]{expert mask generation options}% \genidx{options!mask generation for experts}% Expert Mask Generation Options} These options allow for a detailed control of the seam-line optimizers which govern the mask generation. \begin{codelist} \label{opt:anneal}% \optidx[\defininglocation]{--anneal}% \genidx{optimize!anneal parameters}% \gensee{anneal parameters}{optimize, anneal parameters}% \genidx{optimizer!simulated annealing}% \gensee{simulated annealing optimizer}{optimizer, simulated annealing}% \item[--anneal=\metavar{TAU}\optional{:\metavar{DELTA-E-MAX}\optional{:\metavar{DELTA-E-MIN}\optional{:\metavar{K-MAX}}}}]\itemend Set the parameters of the Simulated Annealing optimizer. See \tableName~\fullref{tab:optimizer-strategies}. \begin{codelist} \item[\metavar{TAU}] \metavar{TAU} is the temperature reduction factor in the Simulated Annealing; it also can be thought of as ``cooling factor''. The closer \metavar{TAU} is to one, the more accurate the annealing run will be, and the longer it will take. Append a percent sign (\sample{\%}) to specify \metavar{TAU} as a percentage. Valid range: $\val{val:minimum-anneal-tau} < \metavar{TAU} < \val{val:maximum-anneal-tau}$. The default is \val{val:default-anneal-tau}; values around 0.95 are reasonable. Usually, slower cooling results in more converged points. \item[\metavar{DELTA-E-MAX}, \metavar{DELTA-E-MIN}]\itemend \metavar{DELTA-E-MAX} and \metavar{DELTA-E-MIN} are the maximum and minimum cost change possible by any single annealing move. Valid range: $\val{val:minimum-anneal-deltae-min} < \metavar{DELTA-E-MIN} < \metavar{DELTA-E-MAX}$. In particular they determine the initial and final annealing temperatures according to: \begin{align*} T_{\mathrm{initial}} &= \frac{\metavar{DELTA-E-MAX}}{\log(\metavar{K-MAX} / (\metavar{K-MAX} - 2))} \\ T_{\mathrm{final}} &= \frac{\metavar{DELTA-E-MIN}}{\log(\metavar{K-MAX}^2 - \metavar{K-MAX} - 1)} \end{align*} The defaults are: \metavar{DELTA-E-MAX}: \val{val:default-anneal-deltae-max} and \metavar{DELTA-E-MIN}: \val{val:default-anneal-deltae-min}. \item[\metavar{K-MAX}]\itemend \metavar{K-MAX} is the maximum number of ``moves'' the optimizer will make for each line segment. Higher values more accurately sample the state space, at the expense of a higher computation cost. Valid range: $\metavar{K-MAX} \geq \val{val:minimum-anneal-kmax}$. The default is \val{val:default-anneal-kmax}. Values around 100 seem reasonable. \end{codelist} \label{opt:dijkstra}% \optidx[\defininglocation]{--dijkstra}% \genidx{radius!\propername{Dijkstra}}% \gensee{Dijkstra@\propername{Dijkstra} radius}{radius, \propername{Dijkstra}}% \item[--dijkstra=\metavar{RADIUS}]\itemend Set the search \metavar{RADIUS} of the \propername{Dijkstra} Shortest Path algorithm used in \propername{Dijkstra} Optimization (see \tableName~\fullref{tab:optimizer-strategies}). A small value prefers straight line segments and thus shorter seam lines. Larger values instruct the optimizer to let the seam line take more detours when searching for the best seam line. Valid range: $\metavar{RADIUS} \geq \val{val:minimum-dijkstra-radius}$. Default: \val{val:default-dijkstra-radius}~pixels. \label{opt:image-difference}% \optidx[\defininglocation]{--image-difference}% \genidx{image difference}% \genidx{difference image}% \item[\itempar{--image-difference=\metavar{ALGORITHM}\optional{:\feasiblebreak \metavar{LUMINANCE-WEIGHT}\optional{: \feasiblebreak\metavar{CHROMINANCE-WEIGHT}}}}]\itemend \App{} calculates the difference of a pair of overlapping color images when it generates the primary seam with a Graph-Cut and also before it optimizes the seams. It employs a user-selectable \metavar{ALGORITHM} that is controlled by the \begin{compactitemize} \genidx{weight!luminance}% \gensee{luminance weight}{weight, luminance}% \item weights for luminance differences, \metavar{LUMINANCE-WEIGHT}, $w_{\mathrm{luma}}$ and \genidx{weight!chrominance}% \gensee{chrominance weight}{weight, chrominance}% \item color differences, \metavar{CHROMINANCE-WEIGHT}, $w_{\mathrm{chroma}}$. \end{compactitemize} For black-and-white images the difference is simple the absolute difference of each pair of pixels. \begin{codelist} \genidx{maximum hue-luminance}% \genidx{hue-luminance maximum}% \genidx{luminance-hue maximum}% \item[\itempar{maximum-hue-luminance \\ maximum-hue-lum \\ max-hue-luminance \\ max-hue-lum \\ max}]\itemend Calculate the difference~$d$ as the maximum of the differences of the luminances~$l$ and hues~$h$ of each pair of pixels $P_1$ and $P_2$: \[ d = \max\left(w_{\mathrm{luma}} \times |l(P_1) - l(P_2)|, w_{\mathrm{chroma}} \times |h(P_1) - h(P_2)|\right). \] This algorithm was the default for \App{} up to version~4.0. \genidx{delta-E}% \genidx{colorspace!\acronym{L*a*b*}}% \item[\itempar{delta-e \\ de}]\itemend Calculate the difference~$d$ as the \propername{Euclidean} distance of the pixels in \acronym{L*a*b*} space: \begin{align*} d = \Big[ & w_{\mathrm{luma}} \times \left(L(P_1) - L(P_2)\right)^2 + \\ & w_{\mathrm{chroma}} \times \left(a(P_1) - a(P_2)\right)^2 + \\ & w_{\mathrm{chroma}} \times \left(b(P_1) - b(P_2)\right)^2 \Big]^{1/2} \end{align*} This is the default in \App{} version~4.1 and later. Note that the ``delta-E'' mentioned here has nothing to do with \metavar{DELTA-E-MAX} and \metavar{DELTA-E-MIN} of option~\flexipageref{\option{--anneal}}{opt:anneal}. \end{codelist} \begin{sloppypar} Both \metavar{LUMINANCE\hyp{}WEIGHT} and \metavar{CHROMINANCE\hyp{}WEIGHT} are non-negative. \App{} automatically normalizes the sum of \metavar{LUMINANCE\hyp{}WEIGHT} and \metavar{CHROMINANCE\hyp{}WEIGHT} to one. Thus, \end{sloppypar} \begin{literal} --image-difference=delta-e:2:1 \end{literal} and \begin{literal} --image-difference=delta-e:0.6667:0.3333 \end{literal} define the same weighting function. The default \metavar{LUMINANCE\hyp{}WEIGHT} is \val{val:default-luminance-difference-weight} and the default \metavar{CHROMINANCE\hyp{}WEIGHT} is \val{val:default-chrominance-difference-weight}. \genidx{quality!match}% \gensee{match quality}{quality, match}% \gensee{image match quality}{quality, match}% At higher verbosity levels \App{} computes the true size of the overlap area in pixels and it calculates the average and standard deviation of the difference per pixel in the normalized luminance interval~$(0\dots1)$. These statistical measures are based on \metavar{ALGORITHM}, therefore they should only be compared for identical \metavar{ALGORITHM}s. The average difference is a rough measure of quality with lower values meaning better matches. \label{opt:mask-vectorize}% \optidx[\defininglocation]{--mask-vectorize}% \genidx{mask!vectorization distance}% \gensee{vectorization distance}{mask, vectorization distance}% \item[--mask-vectorize=\metavar{DISTANCE}]\itemend Set the mask vectorization \metavar{DISTANCE} that \App{} uses to partition each seam. Thus, break down the seam to segments of length \metavar{DISTANCE} each. If \App{} uses a coarse mask (\flexipageref{\option{--coarse-mask}}{opt:coarse-mask}) or \App{} optimizes (\flexipageref{\option{--optimize}}{opt:optimize}) a mask it vectorizes the initial seam line before performing further operations. See \tableName~\ref{tab:mask-generation} for the precise conditions. \metavar{DISTANCE} tells \App{} how long to make each of the line segments called vectors here. The unit of \metavar{DISTANCE} is pixels unless it is a percentage as explained in the next paragraph. In fine masks one mask pixel corresponds to one pixel in the input image, whereas in coarse masks one pixel represents for example \val{val:default-coarseness-factor}~pixels in the input image. Append a percentage sign (\sample{\%}) to \metavar{DISTANCE} to specify the segment length as a fraction of the diagonal of the rectangle including the overlap region. Relative measures do not depend on coarse or fine masks, they are recomputed for each mask. Values around 5\%--10\% are good starting points. This option strongly influences the mask generation process! Large \metavar{DISTANCE} values lead to shorter, straighter, less wiggly, less baroque seams that are on the other hand less optimal, because they run through regions of larger image mismatch instead of avoiding them. Small \metavar{DISTANCE} values give the optimizers more possibilities to run the seam around high mismatch areas. \genidx{seam line!loops}% \gensee{loops in seam line}{seam line, loops}% What should \emph{never} happen though, are loops or cusps in the seam line. Counter loops and cusps with higher weights of \metavar{DISTANCE-WEIGHT} (option~\flexipageref{\option{--optimizer-weights}}{opt:optimizer-weights}), larger vectorization \metavar{DISTANCE}s, and \metavar{TAU}s (option~\flexipageref{\option{--anneal}}{opt:anneal}) that are closer to one. Use option~\flexipageref{\option{--visualize}}{opt:visualize} to check the results. Valid range: $\metavar{DISTANCE} \geq \val{val:minimum-vectorize-distance}$. \App{} limits \metavar{DISTANCE} so that it never gets below \val{val:minimum-vectorize-distance} even if it has been given as a percentage. The user will be warned in such cases. Defaults: \val{val:coarse-mask-vectorize-distance}~pixels for coarse masks and \val{val:fine-mask-vectorize-distance}~pixels for fine masks. \label{opt:optimizer-weights}% \optidx[\defininglocation]{--optimizer-weights}% \genidx{weight!optimizer}% \gensee{optimizer weights}{weight, optimizer}% \genidx{seam optimization}% \item[--optimizer-weights=\metavar{DISTANCE-WEIGHT}\optional{:\metavar{MISMATCH-WEIGHT}}]\itemend Set the weights of the seam-line optimizer. If omitted, \metavar{MISMATCH-WEIGHT} defaults to 1. The seam-line optimizer considers two qualities of the seam line: \begin{itemize} \item The distance of the seam line from its initial position, which has been determined by \acronym{NFT} (see option~\flexipageref{\option{--no-optimize}}{opt:optimize}). \item The total ``mismatch'' accumulated along it. \end{itemize} \metavar{DISTANCE-WEIGHT} and \metavar{MISMATCH\hyp{}WEIGHT} define how to weight these two criteria. \App{} up to version~3.2 used 1:1. This version of \App{} uses \val{val:default-optimizer-weight-distance}:\val{val:default-optimizer-weight-mismatch}. A large \metavar{DISTANCE-WEIGHT} pulls the optimized seam line closer to the initial position. A large \metavar{MISMATCH\hyp{}WEIGHT} makes the seam line go on detours to find a path along which the mismatch between the images is small. If the optimized seam line shows cusps or loops (see option~\flexipageref{\option{--visualize}}{opt:visualize}), reduce \metavar{MISMATCH\hyp{}WEIGHT} or increase \metavar{DISTANCE\hyp{}WEIGHT}. Both weights must be non-negative. They cannot be both zero at the same time. Otherwise, their absolute values are not important as \App{} normalizes their sum. \label{opt:primary-seam-generator}% \optidx[\defininglocation]{--primary-seam-generator}% \genidx{generator!seam}% \genidx{seam!primary generator}% \gensee{primary seam generator}{seam, primary generator}% \item[--primary-seam-generator=\metavar{ALGORITHM}]\itemend Select the algorithm responsible for generating the general seam route. This is the \metavar{ALGORITHM} that produces an initial seam line, which serves as the basis for later, optional optimizations. Nearest Feature Transform (\acronym{NFT}) is the only algorithm up to and including \App{} version~4.0. Version~4.1 added a Graph-Cut (\acronym{GC}) algorithm, which is the default for version~4.2 and later. Valid \metavar{ALGORITHM} names are: \begin{description} \genidx{nearest feature transform (\acronym{NFT})}% \item[\code{nearest-feature-transform}]\itemx[\code{nft}]\itemend Nearest Feature Transform \genidx{graph-cut (\acronym{GC})}% \item[\code{graph-cut}]\itemx[\code{gc}]\itemend Graph-Cut \end{description} See \chapterName~\fullref{sec:seam-generators} for details on \App's primary seam generators. \end{codelist} \genidx[\rangeendlocation]{expert mask generation options} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/endoc.ist0000644000175000017500000000052012541464343013553 00000000000000%%% Makeindex style definition %% define merge rules %--include "tex.ist" %--include "latex.ist" %% define sort rules %--include "english/digit.ist" %--include "english/special.ist" %--include "icase.ist" headings_flag 1 heading_prefix "\\pagebreak[3]\\textbf{\\Large " heading_suffix "\\ }\\hrulefill\\nopagebreak\n" enblend-enfuse-4.2/doc/config2tex0000755000175000017500000001330312602767761013753 00000000000000#! /usr/bin/env perl # This file is part of Enblend. # Licence details can be found in the file COPYING. # name: config2tex # synopsis: convert "config.h" to a series of LaTeX commands # author: Dr. Christoph L. Spiel # perl version: 5.20.2 use strict; use warnings; use English; use File::Basename (); use FindBin qw($Bin); use Getopt::Long (); use Readonly; use lib $Bin; use OpenFile; use Quote (); use TexAux (); Readonly my $COMMAND_NAME => File::Basename::basename($PROGRAM_NAME); sub quote {Quote::gnu_style(@_)} my $directive = qr{ ^ # at the beginning of the line (?: \s* # skip optional whitespace \#(define) # (#1) match C-preprocessor keyword \s+ # skip whitespace (\S+) # (#2) capture macro name \s+ # skip whitespace "?([^"]*)"? # (#3) capture possibly empty macro expansion | # or (?:/\*) # undefs are usually commented out in C-style \s* # skip optional whitespace \#(undef) # (#4) match C-preprocessor keyword \s+ # skip whitespace (\S+) # (#5) capture macro name ) }x; sub convert { my ($options, $input_filename, $output_filename) = @_; my @exclude_patterns = map {qr/$_/} @{$options->{EXCLUDE_PATTERNS}}; my $input_file = OpenFile::open_file($input_filename, 'r'); my $output_file = OpenFile::open_file($output_filename, 'w'); my $linenumber = 0; $output_file->print("% This file was automatically generated with $COMMAND_NAME\n"); $output_file->print("% from file ", quote($input_filename), ".\n\n"); LINE: while (my $line = readline $input_file) { chomp ($line); ++$linenumber; if ($line =~ m/$directive/) { my $macro_name; my $expansion; if (defined($1)) { $macro_name = $2; if (defined($3)) { if ($options->{FORCE_ONE_TO_DEFINED} and ($3 eq '1')) { $expansion = $options->{EMPTY_MACRO_VALUE}; } else { $expansion = $3; } } else { $expansion = $options->{EMPTY_MACRO_VALUE}; } } else { die("$COMMAND_NAME: $input_filename:$linenumber: expecting ", quote('undef'), "\n") unless $4 eq 'undef'; $macro_name = $5; $expansion = $options->{UNDEF_MACRO_VALUE}; } foreach my $regexp (@exclude_patterns) {next LINE if $macro_name =~ m/$regexp/;} my $key = $options->{KEY_PREFIX} . $macro_name; my $value = TexAux::lift(TexAux::escape($expansion)); $output_file->print("%% $input_filename:$linenumber\n"); $output_file->print("$options->{INSERT_MACRO_NAME}\{$key\}\{$value\}\n\n"); } } $input_file->close or warn("$COMMAND_NAME: cannot close input file ", quote($input_filename), ": $OS_ERROR\n"); $output_file->close or die("$COMMAND_NAME: cannot close output file ", quote($output_filename), ": $OS_ERROR\n"); } sub show_help { my $options = shift; my $all_predefined_patterns = join(', ', map {quote($_)} @{$options->{EXCLUDE_PATTERNS}}); print < $options->{INSERT_MACRO_NAME}\{FOO\}\{$options->{EMPTY_MACRO_VALUE}\} #define FOO bar -> $options->{INSERT_MACRO_NAME}\{FOO\}\{bar\} #undef FOO -> $options->{INSERT_MACRO_NAME}\{FOO\}\{$options->{UNDEF_MACRO_VALUE}\} where *only* the preprocessor expansions are mangled for TeX. Options: -f, --force force expansions of a literal one to become [@{[quote($options->{EMPTY_MACRO_VALUE})]}]; negatable -p, --prefix=LABEL prefix each key with PREFIX [@{[quote($options->{KEY_PREFIX})]}] -x, --exclude=PATTERN exclude all keys matching PATTERN [$all_predefined_patterns]; option can be given multiple times -h, --help show this help screen Examples: $COMMAND_NAME config.h config-h.tex $COMMAND_NAME ../enblend/BUILD-GCC-O0/config.h EOF exit 0; } sub get_options { my $options = shift; Getopt::Long::Configure('no_ignore_case'); Getopt::Long::GetOptions('f|force!' => \$options->{FORCE_ONE_TO_DEFINED}, 'p|prefix=s' => \$options->{KEY_PREFIX}, 'x|exclude=s' => sub {push @{$options->{EXCLUDE_PATTERNS}}, $_[1]}, 'h|help' => sub {show_help($options)}) or warn "$COMMAND_NAME: problems while parsing options\n"; } sub main { my $options = {FORCE_ONE_TO_DEFINED => 0, EMPTY_MACRO_VALUE => TexAux::default_name('EMPTY_MACRO_VALUE'), UNDEF_MACRO_VALUE => TexAux::default_name('UNDEF_MACRO_VALUE'), KEY_PREFIX => TexAux::default_name('KEY_PREFIX'), EXCLUDE_PATTERNS => [], INSERT_MACRO_NAME => TexAux::default_name('INSERT_MACRO_NAME')}; get_options($options); push(@ARGV, "-") unless @ARGV == 2; die "$COMMAND_NAME: expecting one or two filename arguments\n" unless @ARGV == 2; convert($options, @ARGV[0..1]); return 0; } main(); enblend-enfuse-4.2/doc/enfuse-saturation-weighting.tex0000644000175000017500000000360412676175540020140 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Saturation Weighting]{\label{sec:saturation-weighting}% \genidx{weighting!saturation}% \gensee{saturation weighting}{weighting, saturation}% Saturation Weighting} \genidx{colorspace!\acronym{HSL}}% \gensee{HSL colorspace@\acronym{HSL} colorspace}{colorspace, \acronym{HSL}}% Saturation weighting prefers pixels with a high saturation, where the saturation~$S_{\mathrm{HSL}}$ is computed in \acronym{HSL}~color space. For an introduction to the \acronym{HSL}~color space, please consult \uref{\wikipediahslandhsv}{Wikipedia}. Taking the largest and smallest components of the \acronym{RGB}-value~$(R, G, B)$ in the normalized \acronym{RGB}-cube \begin{align*} v_{\mathrm{min}} &= \min(R, G, B) \quad \mbox{and} \\ v_{\mathrm{max}} &= \max(R, G, B), \end{align*} we define chroma \[ C = v_{\mathrm{max}} - v_{\mathrm{min}} \] and lightness \[ L = (v_{\mathrm{max}} + v_{\mathrm{min}}) / 2. \] \noindent \App{} computes the saturation of the pixel according to the following formula: \begin{equation}\label{equ:saturationweight:hsl} S_{\mathrm{HSL}} = \left\{\begin{array}{cl} 0 & \mbox{if } C = 0 \\ \frac{C}{1 - |2L - 1|} & \mbox{otherwise.} \end{array}\right. \end{equation} The saturation weighting algorithm only looks at a single pixel at a time. The neighborhood of the pixel is not taken into account. \genidx{weighting!entropy}% Obviously, saturation weighting can only be defined for \acronym{RGB}-images, not for grayscale ones. If you need something similar, check out \sectionName~\ref{sec:local-entropy-weighting} on Entropy Weighting, which works for both \acronym{RGB} and grayscale pictures. \begin{optionsummary} \item[--saturation-weight] \sectionName~\fullref{opt:saturation-weight} \end{optionsummary} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/local-analysis-window.svg0000644000175000017500000005022412603512746016711 00000000000000 image/svg+xml N N N N C N N N N N N N N C N N N N N N N N N N N N N N N N N N N N window size: 5 window size: 3 enblend-enfuse-4.2/doc/laplacian-of-gaussian.gp0000644000175000017500000000054312566032753016440 00000000000000# Plot radial component of Laplacian-of-Gaussian Sigma = 0.5 LaplacianOfGaussian(R, Sigma) = \ ((R**2 / (2.0 * Sigma**2)) - 1.0) * \ exp(-(R**2 / (2.0 * Sigma**2))) / \ (pi * Sigma**4) set grid set samples 1023 set xlabel "$R$" set ylabel "$k(R)$" unset key load DATA_DIR . "/colors.gp" plot [R = 0:2] LaplacianOfGaussian(R, Sigma) enblend-enfuse-4.2/doc/power.gp0000644000175000017500000000126212566032753013435 00000000000000default_optimum = 0.5 default_width = 0.2 fwhm_gaussian = 2.3548200450309493820231386529193992755 fwhm_power = 1.6817928305074290860622509524664297901 power(y, y_opt, width) = \ abs((y - y_opt) / (width * fwhm_gaussian / fwhm_power)) <= 1.0 ? \ 1.0 - (abs(y - y_opt) / (width * fwhm_gaussian / fwhm_power))**4 : \ 0.0 set key bmargin center horizontal set samples 1023 set xlabel "$Y$" set xtics 0.2 set ylabel "$w$" set ytics 0.2 load DATA_DIR . "/colors.gp" plot [y = 0:1] \ power(y, default_optimum, 0.1) title "width = 0.1", \ power(y, default_optimum, 0.2) title "default width = 0.2", \ power(y, default_optimum, 0.4) title "width = 0.4" enblend-enfuse-4.2/doc/seam-line-visualization.tif0000644000175000017500000042362212541464343017233 00000000000000II*&xyeUu<$̃"sA1XP mPmi|6m416&18GEEE( 2.( +Oo6O>E]3뗿̙3͛wwL6{`B'tfm(O9뮻u]Fmt%vmSoN"k&kO`)S;\PنnC]-kqwnVwB -tfO}M7t 7=;/zы@s9Nz7_w^ꏜr)o1,ۿ6h#X衇z[n9P9*W_[c5+ \s^_ve3rє){E L?{QnBkK/t7A5 i;̛wb-_Scyrw>,X{6:TE] _WZK/ET sLC9u֬籿= 'k&gK/]Z/omaֺ{]w]Gy+^ Z0:묳?|{p: L2u^Q20kƌwyk=k֬_l(Ѱ|򕯌.;UHyuס_5/b(N=r6`}kr~~`NpK3|IPB -d뮻Ι3ǟ#9 ᯊRȖ[nyw{WEg}?V[m>;znx47dKW]uՒõ[̞=q37lp{^ M/6eUV*oI5\SД]o6?s׋_bv(htnFO~r-Q pmp 5[oѓk3@CPAMR(+PklVP車`_CX]_4mj!؋xҁy.:= Vy]K._/3hkW\b_gurСSn?bkv~UWA8D$H, 8묳sϓO>Y-r)1mX >lpV M ĮJ͟KLFbM^LGzOW^G<4@V[0׻NFXjK?tUaHOzF#ɿ0EW^y]q(Ó޿k&a$Df`e]M6ylf` dC; K m&s~|&VrAS;{K_zM7w}7.b[vL /Ǽ'7xJ/Z zTA /[{Q5\N#8CR8u.(7\poč믿~GC=]h&p7ӟ  ,i#؆Hep [la- ڝw0:O?VmQ/쳏w #2wѰNW Wpˍ" lyK^AyWiZ=}YNvmt[Dj}ԂEK+ԋ< 78c> w5Y!DJX|AM["8zzΜ9+z0'z'C'k&f "&"pˆj,2{{8ófb1]vم]kXK.>NXvcw޶j?ޅYge]?!Fv-5z7|ň+}_ɇ.HTz_ZXٳgk=|;t2a 8,pHC^,ڒ/}Kg?bFL4E)cȃ+^2\!믘'ċNϫ$kզnz7z(b@)5c p,oQ[o xvg`,uyF혠8O,rr-]toi.}ჿpPծ:kW;|G)g]zP+/opb9^ءNh}Qmz6jK˴i.bdL2Z1uԼ|4 4'|!Ǥ&*1cd\{dR9m|O<__Fp&od0vƽ˴0 謼\pkY;4gv l{^Vh:ix;$&d4GpN:%d 0X im;}F_q_`O$Q4aW:K Fnyx-馛; s4x՗s Q<lHlt;}4P16\4Xi\Xg}V@J}kO8,m)Stzb+dn|a}ZxIf(ҏDՏcӛ(-jrqخV=2C*T 8WY|Š]vYiX %W}G@zGwcʑ +O1Kc ky֬YkR}wZv{BH{|%t7=SO?v"O`? c6R駟n]3Cϗ¿$&kMwډ512wY%&=bV]uUbΜM{7qW[o5sg3@H,T1Cr 8A뭷.}@>uOO~)SmcO˯)r(2hyڼp7ZӴ  #5`QN&-7 I7Lw]Q>H0BFup*Uum g:x/c!҆ W/ P) }M+QA3 Ѱ%c u]Ovq`uѐٳg~{%mlY~wa[n] nh4B 0\yZexӋ: )9ēXb 1/nѡdF=W HˡM1{biqI*Z,\lX(MuiTCE>ymDSO2\{=tV`뮻iOA~1\7 %Ӹ(W ~Hr|KO>{8o;eYW);ms01G-p)n|)9M"k_||2,NH\yUW]Maӽ>oIkc:TQ>Xf|%;Ҙ P Ys5V/~駟QI0D^{͙3Ghlϟs9'.V, ъz.BM҄4 +V*ua3b<6E fUIe.ñ96\* |F"Ջ8ד쁻2* sp>ģc]1r7AO kvP~Y= - I| @m3[+»H"?h2cp7(#=*%ۄd ʙg΁C`FK/xUQ~IZ 7ܰUu2i{vmID1mڴipao%խz+t)J@;fip;B뮻~뭷"-$P]s5بl+tP2<#4iz%@_wݷ]vz7th"nj}F}fH6])JOmvX F 0]n%W> 0jY|а*<*֭~F+S' sǍDzw dhrJ\M0v̓սخdA$?$:7޴"IwjVXaKBVQHW]hk I@'Py@R`/vyS]̋2=P$b/ҖV y]*tiN9I%+ʁ!s9/F( r6h1n57x#GG=z{.:-|;տݝoѡW\aj970ۦ:'=Oo 2ÌL 3yM^]bH2l(Ei5̆$,RHcȱp}/.*1[~ 2*x'vB Q,KΥJўM49jc{aO+~JgMeڡJ-8Z^56L/"fqUW=S# @g:-E90ؖ:J,Od+Kh&k;T-g2wyJu 7(<'R:j>z˝FQl 7I߽^S>5N`/[Lv2qIQv/X7氰!VxQQ@ ?묳yk̙ӛ+#c8P $ނlr %^_jci@j;omٛq f&{ 5>A?绖BЋfz 6?-BH :~?9<[%xCHQ/' 3g_xGm?`zƎZ+WM&~b˃ ǼKw "IP曣Н7'Ԉ+$*9CH !QDZMe 8sϽo bvSQ^8Y2ROb]mך7=i?u?o98[kli,`A( m2A_;{0(0^ŀ:DyZlYU#OZ: 0=яuAbKX=-~jzus6bű_4Mbvӱ m *pM7eΜVXaw/s|^ABEH} _h[Uh1IÿɭEm vWȰm-kSl0rUx8:" \&lg}eJXtG=Jz\umhUBK~bB[x-_. nj>s"U7OtI^l~ +_ ٳ!I[wΨ%]mUOyEOb9k7I9! ZMm!*x^c۞6k F"9mݾ/o[cùs7$ha z„[nuu^z 7ˀ.Uڊj@O?¹Y$sun-~wF :u0\ʇ֊M7&`~{k0{h07a_84FhQ"JUjWQֹ} "-]{T{󹵡|WtUbMڛ0NAPqGnJwӰ Gm ۓ@G!˸ gw%ǝP/%D da6h87Ý4LK΋VhQ`,jcOE[lE۱| .j}u2cv^J~>B *@, `MozWBs( 袋0UAnZK$0vBPxf" k]sͷV]u;^/Q/8J9%z=Zr$O{w5ğ&b j/C˩MFʎpF/0XUjzի("Zrs&oF[.]8?Bhc_|>,Z{xyPQh8V 7t  7@ᯂC -Xp1L Op‰[.bP"oڥ8@lӮ>xu;,V| {}fE '%{1'!<ۣޡ-nAIk[m駟vv^@8@1$P^{묳dy Fk#-A䌻o}[2RBk֙gH;HJy&QFt) %RgtH{z 0ebzqw;w.b4oQ7ʊ]1|筱LX=s̯|+Ĺ瞫fPHpt+ՉTSpw#8XW[6mL_ h0"-Mr=e7̙3LR+  va\~~3%(-$a^ 9jAuCZ)g&UWb%VBWOjҊMX: G!Ğp·*y,b=XO;\@)*tC6?]vzW[/R d p;:bg4_׺m);ve|EcMr'|u}{S u~j`gȶU|)!Gj]-HV5Bx:a Nj[pN(4E\+\_PMZOކ=}U: jW<9 3{@JBOd?ACڶ1 ci1~v23Z ]gҝcB{ }<6km}}V^3Y]y|io+F=S6^]cOM2hYy \r P{gIQd5 m:HgYgp|OqǝD IN D]}IzK, b 2![)cC/>LY8 ,HrfRno 1_K} B'l7_]i(#b`ѡy9r0 lY?`NAz7>On &lL;NW?M"*n5I{wbðv&ҮE- YFDh$H]8[(~SD3 s 4LЪ\S Ƞ@m6(74МRFӟVlF_{XQmܴG,Phkc =^Bf1[ʀV N-"z+J6N[J'RxS ^PAe OiѰm5tBcK)&?_*_<,Y{XʡGC.2x4*": G T]V"@+0~+ݍGeK݆'HEᝂg*:۶ ZT|')o={; MAX=ҞexEK.1꫿J{uBMC@EGU׉'> \YN[1'M]Őj}0_q?%u2#4c;tz9a[NA^>z|{INI 0ɂEOL GDA;%={ Eq~#]Iu@[pV+YٕW^y|N^id!GK 'E' 6DQ(zRFīT+8z}T?)?ETK5)/48vm>VwhoF $7<9˹$>k֬&e 5ڎ(qЭ6"l'T)]QTպXE:gk$`fr]efk\ʫ~~9?N>Z1yJC.Eَ7/ _$Лz!-9oNȪmriQZrA۱B0QɗOR51IWM '7xÌ\VGa>R5(StcD/3أDD8%& zTfȤe>bn+Cӊ Eq/-*JКW .`Ղfऺ#tAKeOjuI2TU#dZs}) w~`Z4YVcTy3T@T~Ѱo"[LwRþy-/TΥL@>}=re1ǧm<<l426%D.pSQUC6:rQDX, nό`Z$AW ϸ؎<'_zvHM=łSX/4cЩw9}ti?ewZIz-9Ј!!d_[V5bBzK쓱݄?,_uSGQ3CKk("4 oh^z&ffqڭ@<O=!ŮW;nz/t*[*-˗ 6@,F$JʲOIz Y GÔgX.XyjY"H{~vAM\Ё tmT1vm4kJqD( !et216^4ʻmg ,g؇WIuM:ٍiQf=v˜&ɻ=j6af<6}Zl;%~itknwt_^х.46(]'Uֱ> lCw~|<4 TQ,:' l uRrе )ƿ TLw}{+|QCˣ!<.Ucj*` `uv7Q9( 6r32Xν袋Jy95⥙ҴxG'ZߑLL&` vi=38#P7vg'YeEz:^{ mTubf9gwA6v1F u4t+Q/0lD r?i'sIz>nQz<[n?0w/ V[׃XhhCyĦ{zoHoծFwh4Q|l~/ iB_$rHZ7;;.&fm  Qh0X8 kSŚe+줓NO2YoEuς+jZUuByB2?fzSTxw:*39ahf݁x 317$)OaDw(F E;(P ҎndVth2ṘR8mk2jUQ;ogoK.t'͹o J|piW駟NUp&- sGl,Peb.>K<`h`(2?Jy;p!sݟ]\Ty%w=\yNB ()U0)CT*LO@)*>!5AA-bDu3s4]' O:iu/UV~s[sW]u^bz\91B8¢V=}ثS}Ek|N ;1'5Hfr-u9]-zWUgAZz`໾+qSP,t҇V^yo&&i)OJ ?ue+aZ,rNƅfC&.c$3 89݄CN9JyǓ4UPzafhrIh] -Q v=.cޖ?*+H^!zM`yq[9 ҕkX(hT*ʼiB Cp[o*+$_kEmp :t'6VhzQ[*'tDfhMǕ _hgrK6JBz㧻&&wDzcTiP{aQb kG~+jug3/206|jo),M Գ(|d z iⷾ 0}{Zvɛ~){aRWլ )n@+Wқ3, UNF9q0¯Dh~mDO3XҾ`FZT]|#,ҐھfKb~*!%!qvcץ"!`+[zv<@3N-]Ù.Eb}__ٙ͟H5iY>RRmjhsZh.Qug1QYפK1UZCf̘v-d aB_Qvf1FG9j-9e4 PR)`6d%B :9sa5܀e9[CW}jR;/qf5m-ǫԌ^nc#W|g7`}V/m2X-]f`Sŝ/#u '|2ЀrWD"EA.Yx6E]B__7gWxbS$ U#K-zSW5#i֫1|/S43_{vOl?h WDP,X7U]lk^ o)d)4Э=\o&MRp3r࿟?[?I5lk&nvo6c?XNo$ F7zmw7gtg{ojA^fk>W#O?mdژ 2|T7!Ivhx.r` DzJѹ;Fe1;~24L 4b-|}AE"ҮyLr @sU4w4vg@n;w.J[9)O4і:#B)x6R]r%T7{ rSGxxBoȴ=M2okx_L#tYl)I-|"5lZ._FhBz=m{gvr{34a#>O:@0bD4. ]KBnjv-\Dl>J[r1ı"gPc6ؤ,5Izn"IQRKK -G[%W]Uw|@pL+949МceyX1\b֍h4x4ٿd؂h%*-+ԇT^5u[c.n;IY>I{>%;[w]Zҕ =S\Vg6svJI`BtY2( ѨYfq||^?N;8^{*}iniTc_ve0ʿrʴ :3.f@RW47 [B( ֚S&(oy&3y_>=-uy V-bNA˜|k?% LE~ߵB kp/hϜͧr'lCNJr‡Y1,ud0)*X3Ȣq/7{ün`66;#yݷ[k|ϧf4M+9FҮsÄaf2j{=F_T'TDd[e3O rx=$0}}-F8*(t)ilhQЖɤ7)U=@i;g#"TmV9 =O9.sF4SQ7Q0"`UcrKL@Dki);/[YiNrxr {[.D ajk^kJP"lEFUͲrl(ѿJ[@苷SCZ3*~c¥ZTo~sK4ɪ4XL˵W^vZf?Y?igv8~ _,)*'l/Noc1Q%kEqo~hɜVj'Gs5loqr {^t 0HָKi06v :wG62f;*%!|FM k K^xqn+k^ɒW: 1Sif!.ΝXr8e,ޞ*3uszoQ ryUxs)|H]tѩ1jڴirPVBZ@fMaZmlCi%G9bvG`uN֡e^(ZmA: NƋmܖyjKPnYgyM)ƶvTtWa ۠fmoo~mJg֪sy9fcZ0V.d(D)@;aT:򤵋9e,?5|ɭHo? )Ba@`R ׽uBjԔ@+l%{ک%K,@ 7|ܺ뾮ˉA vDpZ~QKa74h4/pޓ|ry5,#b+"VΨE3Y{aUx8a Fr4[ 2 MHE f}VڰY[>R- oeE w3/GZoT&,hB{\${M rVqCb?elxbIP޺Pgmɱ쭒0Wc"]~4pѼ6ls{g,C a3?? D|31ildtAOJ+.]鈤 %n)trO`hݖV^ds&N`L>`cL(i}49 VoTJ BOt S~W0r=}F6};ߙ_+o[q_~ ҐH&?y;nدY[ޖȋIm6:\u%}tȎQ:cybi\E.6݃|i6 l6Fe.2I> ,vѣ|]5wNqN=IWq#%3FBetNϳm͕1Ӭd6(0wH˅B3n\Le#oN y ]m[8fl{֌3F)Jx<֊+!'7>ޙ.βkWM(4BcprN! ܟc9ӄCiQv&nL J+T_േ1tݢ8DޏeoUp@3omg_f( nz24aksymhJPsbSA#F]eLw$Jwfe$c::7i, *JǑPz/>fe^U7 `gs9'-]@|ҥ^,*kD1OeQӜO~hUJk&O<ĖoXRd!&G9:qa૱ʫS|/}m<6Jڮoi:7^BM w~GfD$: ?rwb6ƛC,2QRJO$O %.?_zm}`Q h@cxa -^ 6cH;!3dq*ZkW+D%0vZbTGI7j~hHTf' QT7_/n%iT‰-m:%')2I9Z }{oSؤZJt\Q5ޚ5kVO;h"e0v@m붣aN;o&7?䀟JvϜ9s' NK;:3R=y(9r|{]vc*AQ,zu(zi??izē_~j9M}k`SZ@5r)ղ#9 TbxX.ӷ&]x7vnxᲤWlAjVSVzHL Ѱ@xyl^g|r<ؖ&t#MFhI$Qw5.-sߗ%BN;?|wo0`2{n X퉽TJT /@,pMyt.2QF^{EɣF>CD:Trt|;xS]CBs笳w-(}Z̪2;+H-QsKAi\ dz~s%vTQEzA*ogH48%pȡZ&;-bqGm6qkF>b{ʑE?+-je0x|V^ΏP^//KOkVd8, (IR1x O6>StQ"wcX/H!+SZ<?iX ۾Lv42lwZӫ-U z[cZk?Qƥx>ؓRp>ƶ9_tҊEPw@&Q+"UF}G5gi]r3f([[o~>)]>W2 >s:O*iߠrδL_XfכЃ5DZ{y޻ F^_tAӜv0PFh XSl^ [mu)9[RW:WϞ=cr)kE pf9/Jf~j &d!Ib)&!O̙3ˣ2t'Q/R"ذ%0jYѰm n|P U b/W?°倎~ Gp%cJrʌHЗVKQyu 8U]w5Gq} \yl7  |zd׿E"ӉZu-e|k_j' W몮߫u}!sԶJ {fwr?2#a67 ejH>񏏞a~I - !iO{zi[P` W;N?B8SZldWh!d5,',>% Ic)R)ik!m^@tUXJZDXa*N %6hTrng5|t@4|ח/CO[_?Z/*vHuCN+D̓p. E,<1pRK<^ɉ4pfԪˆN. LKS#%lMYmN.1o.EYޭdcـgz ׍s#WKjXҘ4qs'N14z Tu[n9~nWfPo}G҃%x)&<~8Vƌ[EaY(gm>%Ve>|_Ȫ*bR$ٸb&Ä‚Xݺg3az_ZK."`Fn{lqś< ,9N3YΩaT*]LQ3'|rs+L HjAv t(U𼔪`ouƵ'KbT"#z-l.Z/waLhHcUTzSIVN{$uzӮZK;p Å\-aOli_ :Xi{_]ŖTblo^jNj-5//X Ń6 UVه&8ԓb qz7vTbvm9p"|4 /pC2a~ ei+òd͖ %j #O<~:]9a%}{1.>9HmW h7k,zR Jߧ p;#bxYS6>_fza_z+UTrQvbh"7cy/99WqٳgO9nƧ趍gJNALR 2_*w=#WڞSZC9rdOE`5?j-ެNCk;'GnVwzFb ]kM +J3aO?}6SNpsrk܎wt]f҇dgFA⦇h)R\}s]4+@ FM'O5L|*`NďvѹZԱ HYKo;9Ύ|lqu)#ҺޗPR&~zب$a4.].طv$UD ҏ `ƌFѧ /9[xygN1ӝۢR;Ur3/RQlS 'TPh=+ߩxpbK93 +\-%N L 4v栕q~4c80ܹs&6_h!tV s!{AO<E{uqPXz֯MkXp.>s Gե7oghW97cɠ?|MXL Wu9?†T_49&50afj9s6U3(>V-EL2R^3sբ t`Sv;_(Ѱ)mih?vc{`o+Y!o\uA]m(@hU4w^Ƥ/GɧbZB oiEZw/8toX/J#F'[EFKJ;: ,]ۂ~mxq>ap߿8%hy #+ +^:WYe厏ZNdnv{^zU[-liӦ#Fٯr΄}bEgbԨ6.P`64MCN{Ի"E[E4}:te- C`rbԀ(bګkQ`,H)SBltvR*h|ĢLd=ܓ'Ql[$-'p"~rLt{ѿ B"#Q$gD7.3o޼F=ydSObl6mMHַ:y7|g FX.V(ڼ袋 sn*!tC [7A9j`?Y6ܲ| 1[WmjT#0K%yvM)x'íE4xY8k}?|vabhP1ҿxmk}dMq{f {>Q4)k1NĮh*VkvyVb\!p:#0[qx+z!Rkg=Cu+XкSî׫6y(-ns,Uq#Sska"P|x eecs6|iWNeĵդsIVЋD1uS/g0e\=%LY[ ȎÊUK68)讻ů>6I7Wkg^탪ղA2Sꪈ QE"OjioDی7=%ܸ ^-M_*L(ʉO'yIPH*M&0 |C q&>J`P,L{x㍛AIV4/d7X¹ǘ6)8!3'ϟ#_NS-PcD%Ckc`zesKϮtj8id[ns;6[d$[V,K!S~ջ1GC1xoե$S(v[ $}i6V1ozCj*.˞i).{}mZo۹LGw 9vj4?Xݱ,;Wn 0R7$eT(MUj7HO2Qhb;OI+3^*K\ )S~vi z#d*9Ο( kVbU^;3$DidWVY4? cKoqDD/zݺ42eh(?,nlnvfQbgfR1ěcQ {\{ '?#sAJ [&u3;u }{:*@!5:;ۗǸ` F({v8-DhE$j=d hQuFm#pfɍ٩ W>xOROVܯ:h Mfiچc.!,[DGOݐ [ڙP'EܱM 7"<&MHx^()Rg?y'd%պ4 =Q:0zЄ]|܍60PFؒd)"5(\񰤒xݬXbA2vl6M˕j"N<O1k.: cáa6a ~P /x۞[m]*,]gUX %)X{W }&qj$JN;csKk#;6¼A՟&*qE<܁x@(uűSF*B;g?YC&ɟTϢQ_s&\ªB<ow]?K'$(8##%' [ʔ)N+U,\y4f~b'V|wnQa>,A|'(ڼ=RD.g/WRoŷDUEީ,Qxvq8?>ϞEZbDhIx/?S@LH3smQ? x:*ChLI2Jǎ%v/H<| V9Ώ y}h"k-nl fdC$nPOvdE @ljE[HLlO+hخ p!^-5Rb͝3{=Ivg8/F }xL4-ƤrGƛrmbKlR~P45.@dvx#Eij/ܯXujPn>Ds'NO+ HtjQJ?0;Pw@,iT\obEo6Yc}]NXNŁ.Q?.K5c6AV:-1m(($xJϾ3?F^uԏ:}ټHZz6&((yL.Ztئ -\s5_V5Z/4-92@iZLit+Z{ソNׂ&i"F -t2NxԥN(4Yљ9'aӗ(*DD !h{iK{~+^穇 ?H1^]'ʿZH)HCqNaͮ#FǏVgh1FF$[֤1N\Q0RSնz]VYezG(R9.~[FZ,z)!%9 @j$%$&J $ff,'E{x?H|R?F[8cFy[Y7B9'_ͬIU՘7* Bk!UpOj# _BL+M;g}:q:S*KI54(1$@:H`n'W( +cnhȞU#XO~r _6FW Ga/TݙxEVNX)"pw`B!vFȹv ]ΆH1s( Z)^1u]] |Mo::5F` tF ٣ia4p2Rl 'ϗDK/6l`"_Ij$q(ܬPaopY=!+jWncT4'1Rnɧ`o~0Fb,Դ*r\!G^,-*EvmYK7ZrahC1uT*\BI7/?hQEp,w7 d Ats_A=u:!6&m+<:w?pO_|K%*Yqi3 qBu1;l"3a5֧b]Q %sPG[YU(暯FtjDE9>>rl}ID{3RJUWH璿T- ΋&;ٳRLe[t0LePm,y`fξ]-'>Xt4K줛~ˆn|_7ŤI'WMΓ."ys-ըc5f7'db`QDȽ8J(N8k~^NYcìmZ5ƈIM2eܹL`޿{"8Zh{'>m?|#:cÂƚUA*pf5ٚMLKLߎaڌ3>&]z?(fEtjMz*sÛ6ıYk͚5k7okV!l(7<#,5BH5]o(s I$rNR0;s)Tw}$qV`sN \Nn/.Ϸ}1nXj{V%s Hꪫ*m![ZCc^e$I7R~t1y9v+JN;uUf48w^v"ؗ)0If6'M͇zU3]/i …G.$'54踰apڹaj[ZnͻGf\J&Fr¼M=C0\Ψmt7 +n vn (184^{mMpv3vʆqc2qO]r% 6,f>iWvѨQBA0= ҁLIrL;|qpQGr!^xaFnxXbydXd gюf՗TqD7iЭ&_40|AilM8/VPs!s̑gIVOzjhPo=!hmSkE 8~Ƴ:y%Ti$dk$nSQ^0JxQ<夿 JmTۥPpqqefM&d%5zuG YR QC<}ЙN ȭԟvc/nӼ&Q2]v6"G%ֳX|5opWk-%c`~Zk!wO1&5zMbr|>.?}衫k_6۬ЅzxS FH㦋$Ò#2S5{a'>іA'uge E(Z\ĝb6 X `l^DqcŚR5dr)ն6ry;h75 CʰfwW i@8|T 58q5r@`.\HwX̮^[& Њڶ1̣wZqnrXF$[Pa֦)/[2ӃT4Es$N>v Ju[BSs޿j|_p>z]Ka6fM 8ɓWUMZ3fު0[0d\A(Ʈ(vN-i+@F7[Ob^A3J[E̕Wp47N=T۬/2NFks5u^'o>]wiO[ilR ypi믧 Zx="{H6E$1*ˡb7O~L ,by{_;>Cj7oZWJ{]]7> }'ᾜ5^{6:qPAZűqSHԩS[cvsr[tJS51_36ア( RR_|;)Ozr-:`]К|pQuݯcO?',¹.&t‘JGsܓ#E]2y2 YfS2v6bRG3qD/FF&-}n|qiNҺ&vH̶00ct?hwq5v80K:n¢υv+Hc~N%Dׇoհ=D@0.X2I#|/bpV} aD%UغSePQ-"{[ӽ{=Ѥ>DAn6zw3 ؕ궰v5mU AVC2#c (mm]C}Oh]zɨA#i{4W;GZuOh54ѐ!;uY2O TM#gK01a륬G/GV4N$K ˏ FS/xthhR 3]v\4zk`k4ֵŸGi>R5SV Plih=vZkY'{="{W.Ҭ'e Wqˮ#<Α(kO9#bSP"갺-ԕ(34G2kY}IvZ#RA z"t;AwQ~PBbz6#0iڄsYde RaIttA4U(|RhþI%NF j|2A>ت"KZЄu{笞׉ J`co\"ɭ&"W#JP8rfckn嗓Jև'fd;D{aԘR"`i8-&iv 3аo~ -6c$a"Ӫl(2HM:Z>wy[,I9>"E]Ty{e (v^U/Zɚ5kѡ<>ӔEc9FGK}jwnsJ ?FCs&q]쑠HS@8c'!nGH7dm1S-^Bn7QdTkUz uyƌm\*^׫ߓ~mDj/X5|=kZꀿޢSF13R0;B5Fe7LZhJR2JL S2h U$oaFk=E42E0E򧋫IAUIdO"\wޛN*r-q݊p qv+2mڴ&D@5;h=}o|@]MUXՉWH ^~lfbmBo~Jm7u,ma̙0қo$Sw4DN d]E H$A;_z:kJ+ h[cцr=20[Q<yZw 2uuvH(X5ܠ"\*D˴bo+.Barhtk)SD1;nbg5!N 7 /vߛ߂Ox*}rw8 K?i9lxm{69w>9^{E!V^^=O>$N_җ_j򔅑DC&УM j'M"'XP:wh؝fJ%܈S)L[dˤ.\'lD"f3gNG-A]*^5/u.wϷG=Mt8Qwɼ?Lov p0Hز @'Z77&b|{饗&leKSk%m1 ,w}ۣ[{BqRuZ519y!v4[D$D V{ckR.>ez{R}A ѐ/Lץb"Ĉ4g5rl{JƜ`7yZk)+H N N)V*$~D(']1"T#N; U^]tH@?.}1HcCy}9Mhqi&ذg>OV$ة#=(S&ُC7Rnhjv7aVq^D)+^{mJ3{p:.}ڴ )(t-99&EI?j=0IFƈEB⪷^K??S{Ac{J#jΘ1c9쏳ķ8X&XX--{V:Vx  _t(ihrg▼jH$I1sDcf<#8nx/V(Zta<$^R.vPs==XQ7y 'xMe8jM}7t/ϭ,2A" K?b]e2ąVSywrȚ{@?[owtIn{wݜYc֬YZF:1eB`o<mEwqNDD$.lrTibPX&gN%%" h V^yQ`=ؖu6ۮ*yDEx Pyj@+2!%!CKyҡUF8G]v٥ E6m ƂH m.B|=aQ 6V; D . IpI6*}"~wr.4GplڭFFGۙ˲/c 8ꪴOŖ^KL.jYy˵3gBm&/ WB2oci2 ӔTnb5>y JwE7 }jXPo:KMUΠXש7v{i(P]QP!'o7S6lO{(4^9gΜU@D5dnn9+(s4M5ɐ;Źc~ݱ.:fI[_RMqXv'`x4XG]h.$R`F7Cas'yz*';g;qϧ,Ě9}彶 qqqMqNn;Q:9)ȏPtL|My\r:,gya-D \߾[pnHu3JP|Tt )DO%~dxQlC1sP2=Џ~=[| }oDcO\n:Bx9O^AiTӜ @^?ays҉Mh8G YQ'KHLPlQ2 $bEtܻ㽦=+&ii-ÚM7nغ{^wg FNj֟QYd[l=0h*EL`v̉Kn`/|fոᎳ?z"E1E&iKp{un?ziţ "6&{\8Zm]Gƅw؞A?ѹO}r(?񖷼哟fm.Acc=8 ₓ!MHj6ʉLn2lt^{Qf 6+eY)6cF)SS i45-OynXRrR2=SV`ƹjkW hROTdA]M^r%A%/kˏ {}\HZVaRH5 v[)TܿeO{MNˊ B~Gt:9QaJ7&R~.5Xnf2MjƱ$D톐XO %Aڬ,(T8! F:*?(zwB1㐐#> .&r!6+BETfN륢qۇ*{61^uU*"+"2͐NgqH-è.%K.QzKU/J+p4qQ`{QL|[mW SHwm[tX܌gb{m}Iß1SΝ~N)U?{bJLz#~Jジd ]mzNZ(I^-ƕ34ԦOQK’P)ELHgHP@!h0Z-X@LoOEuզ3Hs`'u{ @jD*XDjuCMp}kQ)5& VKDw߽$L)\ mFXe]en<.@wǔ^tj[&L]q [)z.׸S)7SiZjqp|0 ~}kt}'΅NÑk Zѩ]6/o7, ҩ'Piе^;qtu%#MW;ߙF /[{[69P :$d)lDU`^bk3$'QծtfARJRIWڪbf*5֘ٳBe'UZP[L_g.^Q%uw~@[MiYd߇G}Y2YlPj }T'ŴFc!L$19)n![RzؿBsI6&&zHWg! jUf 1v$\ERQR3U{HvH5f5,.tmmF>jU~4K Kw?u`؁^;(Óf_cB*%>By{{'̲8 L$uLMHೖĥ?9K/ ~=lYC(mvAit4VDѶtĜJ-3l:'!\bXQ$s\J؇zx饗biKD~ 6xl8lަBZ釂@(:W+{oJ% vv;[j&iG5^=CݮYfSbc p 1~:%?UڿQw`#ʎ)0e2ȫ4T5kv*qj4XN@W{P,6Cm 2^S;O>2pHTnUJW ,@:l7>࿫ee>8YXZ9t[}Dܪibj>[m.XRGmv1,bMhXeW{4瘖B G۠z˴i>1x≜cazNw_<0 VbJkƕbkHOX)Qm3 UN H0OD6>fҺ\bUCoplf9L>{TUq7=!)\h 6dj0Blܒ's- .1cFsԸ`t/NE:*. 8'2HHXӜ9/䄴Q>wQD#lWZ ?n](ʣNo.?;zg``_惾›[;bU9m.rKg :7|\MESeQ; ܀dF*~(׻v<44emlmu;[{TkuTmOC+U]֔Ėˣ*a@PUj?ػnx#` d~{ȁy|qНvޜk8C-"S;h"6Ad-$|lьOS"sǸ.'3X!{8Cb{eoLdh0@h8%Xm{ϦDaf5r(hl1SNfGY=eUaի߶&@wEZ{_݃yN vI)*hf@7¶I{n?dgV7YcЃ6tY Fv@o}]*:hel0^|7̌Z +P "}@g Y~pγ= e/jR$H |f].]Ql"/&(ίiQ fm\4%pvRz msi3+YF{0u"=$ @%rW|Ww%O ZVIPV2h!.6i4deaM,U+ޒjS/)Y}ۣ$gn@ F76ҏ{F$RTFSJhI6q}B$0lbfRc>s1'= Ηr5qȂo.ܲbnNG.G{iAFs%_~b z_UA#k}ҤI\p4U9Ci&$35;O܃Yf`g>㙤24VON(HlZh̙"FLH/i`0raD7 f{'`֪@ 6(xJZ9ڊPr)͑s;];>w[+hUJƲ6=?&ԿCKd7ʃx`me6fs!c,]_uUDC==^uxӡLý8*W'+P5zwnmt%zIT*T[ 7[ԇB▲8cǟTѐfb!sr@g_z>i/ "zG_YxʻdKHJQh%̢ksח)-hSlc uL܎/0 w)";ۿ={4#8 Z3R9!,m u@h%IDhueT`8lI %iaʌL2mOn ;pBFT_!^m5524umʄ i>l2PGۗ8k["!8ԷCoDk**ILJ_ٖ/2cvK=}dktmRщh-?|Nև:N;cws{aϼ+TČ\uO ZSyIo䆧/\ڔdqcQ-~m."KG\NMF̓~rZkHmq12;q MGC!SSP][.䒱O 6 w4u,"L6Ίa#'bNf{#k` Ig+4C {5SO "]ܵ瞷p衋?v6>f/_QѬv괷 S{W 駗>i+\]*zDQZ >rN{,-r@kC3}Φ"j$~@dȳ,z{7$!&5.ec!3 R-52 \0Dk 2h3}48O!? ,}oI{u4/JTOvi}ԿPMwHG/ՆL~g;KOS оK.M$^¿V R cTj*4TtL[l6ѢhFKܑ,q Ph7ƅԵ^p@Y* *]ZZT=;@HL2@p5fMF7w W 2RYH\oS;$cuqw<ƚLnߩSvSj`Xѩx|^wGsEI= FE~ة FooWCG(N7g4mv\YMDNkbCc#l"t$1}Cm $'r6[d7T]օB7QIWL$'mm4K.IU5 0vm|;ߩMzQ$`6j;uj'jyjğ=C-;제1u$bܕ&Ny0a SkB^Q%Ƣ̯h"7aYѶ=YW̥~jtO@dW]UvoBU]i,g\]:JkBzڊցs璁cM FRSSTb0bQ)HDhgy&Ob[o48nu>p\_iSz+Zb:aS'>6_yj )8pO`_UeP)* Θ1NSXn~/?yltt"UW]D" -.PvA|ٺL^lƱCw=7 7n鿦x >LαnmFWCUJpŸv[79<@C[j[5KAv'θxIx[b@Ԕ/i m[,qW2~i~ۭz԰l Tvo}gQ0jYf eL*W*bۍʠRzmPz$՞>ᒡS#qxJifϞ uT hZ|N DײۣB|q1s,9T $.\4Xz׏m2;@t8> =.p+IOuEvXk@1sLgI0"um4wj7,fRaG{sq?)ING 6 7N{O}uRE'yƌO~6R()ik _qz궿=O.%fX$_Uc, 3(FNl?Zgq'7|3.dc 'bWEJ`PERdzfke.<8^Z*V8)7׿+]L `1{Xc3[C9Rƒ>X<8A 73?яJ f~RWò?1Q"B5$45݇??gQ :aK&Zr[qd;!?&|+y?VӸ"mrYO6SO%E icjg>sرdEOoj0GP[="0ԣaUB'X kwAWFѤ_`Sݯ,z& -,I{l 8k/k^/zӧ\#A=M勶<5ǘ-&{lms TKu={>>&TTT#0%@P1!ٶg^pEs~kݑBW`eY7)4أLj Pi􋝢DXFڳV[r_ւ2īG@^l;kh HcWփLw5'kFbId.7NlhЖ!p-I @PBc'MP#ms'xb}VYo68tA Jכ9sz¡2'|KoRҦp8 cRRe>3Ή%R"l| qcl975m95 yK] f? ;k禛n=u\$2LԍJ+޿x yj?^7_6-Wm|F V?et䛃j!`κ`" ?`8\қLx/|_lZPb$J&X M\ l8ydvvHjUFNQ鵿 Լ8`ͲɧNhJPy0X+ ~cSN2"$ te>㌃?5~2khA,9wRT| 6 ؓVܟE}rՁ7ɬ攢YWV{einmvE\{uQ}ĥ?O?|B| }4EJQ[L\)2A)}oCL$%eٔ(k ơw.7|ZD mV|Jؤ'~%eԍŽPI!!+6j ^ Ǚ| NU $;Nc6H\1|&if ASCQ S8d=hESA^5$*%u' NJ *y3Xc2etK' }&Ƀzx{/{ֳaKj@j54Pnw%vb6є&نn68gqQ!RcDJyrK\Bߧ{DMK/DDH>k"ښz_3s5׼k02ٳgsl).,Rqb@'Y6~~H YT^xaN|;?58^lޕpVa*"մx dl62S%Zil0bRh8\rIGiKJt ~ cwFG>LxڴIVhZ >1obyj&Tab9bm ƀkVyJ?| +ԶvOs'r|3iդźhYuN^O}\KqcS+<\}Q-(W.4eͣSR|+c<˿߄E/j Hq<Բ3^L._ Xb jHQ6qv?"^HkwKҲF*BVQ T"y;,'??R{߰<'{LX#d:qb1zׯ*Z0[biӝn୫_W\Uֱc2,/ Z[[ֿ晉R%[*Iɢ;SX5.hg4m[4Bĉ/fޥ HjJwE'4Ѡ8SIF-hH$ aL&j3W=eҎ?>o6n[` 7z0C9裏nO+8}}O5 "l*BlWuN (m"dWCxbp7 )iR@TG@n!R]LȢ5.nO>z\'d:dԦDIOͫb>m]Sannv:`ʡnS/:צ6G> i NKTEv=ɤIo;ꫯx{f:7O$S~F{N;tg8.BM (mqp={BGՙUQls'P ggk@*Ph䃸M1W9vǣgvX7p()Fy_ mm\]ltMQ;!0}Y,ʣ8 ^xԘկ\rɍ4 w[VnB4w/cl̕i֢R, $ƓlDGzTMܾmDf+XMK;e='<%6ӝ|警s'Sl&XKIv*x($JJYäzJu<3BAh*#༖> fLIڌ 1L G*xnI- OTΚ5.%WM|GڒtБdx[>:ؐ,bV(ڛibKԯ|Yq-1CZCg4?) P?hHX=CxDM+n<"73aK͛ב:&C9Z#jCIth5T7 _'ګs}RrٶҚmJHڌjIz.,O8iYQOo=tduB8Ld=JRk 괗4ǚR# `wɓN; [,f1 dtSդ7=ۦԩg'i{"M7"QD3gNh#r$?pKg.33J;Hc\Q;#R;K3Mۑ[#c曧Lf2cw]W K ^zhf 5WMfrT_0&aT82 zcbdϯ֞ƧCs'":+Sho[oIv }_f+<%vbeUwB眤 'Uy 4  n85|r&)i (E{{3[(&痲*KX=:8fRtLyo"Zn?kuj~=?? gNՃoYc启m}Vu894==c3-7pɟFAJ;EfMM)DUcZ {C;4侷O[[ !=sKoB_k]>,XhOQAuѹRLR5$ykMW.W{|F@`<%mi; U{ S=c4(5M hD>NiK&; ~ڨҐS]5j7d2;G^M<;6DLҔz'jN3;Xn{/x[lU*(\!NNid%-3ϔ-+w,) 2v%c\5放*x0UM p4RA[qvy4.EvډGѐWj`Lu: 4 [2>cslSY;`xe8t2mEV+f%8#s4 8DBnnXI-j3<7 "h"{v6jj, $35|j%6 qBu R,CX؜IKuO>ю7{_~Z,<)N-ծ\/Rm Pl}kء(O*nAR%VSO1RR);fޟ[x(տ?ݙDoVf+16rTǕi*9ߦi6mZU1j;w$;fl;^|/}z6?Aؤ;9%ayʺ!ip!?FK^/W +Tm`[ ={ u5 .`Y?ΰjT55֘)9 (謎Q'b5G嗟4vo?bU<VWW)u8*:_ a2$2!ՄL”IAu PuW`hW(Ѝ 390e 7G2K-&dvbWU~M:s1ua><ql=gj` 6HO5.ս/7xcOӧՆFK uUFGzwXٿozgqRqq3u#3~]yp׼\<\rԩSU1{K|]vI)0UW]2xLgt$OջzukxY(PvM||kr> 9l(6 /xWe2=1?HL^1Ʊ"`:|FOW\' 6O_n8$³jzן%85%?$NQ`PGFKx[IIRQHjS ͭ::bM v1س[lEU<#[D0B b9[4&±@юDZԽKh8$ةm"bDg7Pjwъk5/?{챶#58zd^QѪIE[&ST?uٷ֘w};^Wx(տ ZUx1A?dSEY q9ם8\L~ŷ{juOO~r񳿙kNF9mm4놺֊vk)%9CՈfgN8ZYjmhud/| Vo|Nq/r(1_ ɚp]~ޒKnWLѐLn)IQu8UktIɄ6iRk޺Z-LB.lؖ|^c磡=z&#C%Q nGCBEE隣ա>ҦO򗿼]Mg/d#^ƒ Vj&UbY0dɭNiI'$׀<_l)W:<ܺ"ywy檫nzEs-hv}MJ7, ZB ;._o%Hk-U . @8qT"p*dWc逐'ިNRW'4 ֚dT ;vs;qK]&A[$ n;pH{,Jχ@|/XԶD5\e!&Kmӟilm mCQz9rO|\g"SSr=y/rrMXN>hPD:.aKdL[4|SHm2D=>{ek6#H ժ;a8bW7%=+ԝJ&0м0o}[ϞeݬG:omЋ^W2:MN+]^z)OdlpW~uz>S!j$bLFj oi49uP.QqlI*]lFaX4ԥT{-(:yYf`_eS@~Ü9s6Guݶ܄5 &{A?cu;=fc]but[pz]](]r$ү +y9E]T?V=NvN?Ng TRPtߟ.(!嗟K{H<ۃq޼T=Wj!Q(~&;;'{@nP%7|QΦ )4ˢ\]o. 3!' zM}}\ֽ~eM+l`[@=l6ӧOoƯXnG_bE] j97{KchThq/g"ai4d5ԃ:P_}{5V[)p~j{mδ@ SD%d//FdѸ.UqdMʦO^fMnr9أ} _R#p5iBZY7j8_lqgc.5b[Jm];jE]d6$a}F"t㸮G8-z::N_jQ-IB"9!V Pu(~1~]iE M01q:['W_g?y'>v_6 @'Se A(ipR$*AA[kD\/j:P=0Ggdݜvsؗ8$:0N[hiS~ N[S_S}W㒃`I`lo{w!4GHWW[z ε&a8nvde#1*҈Z < t3O/Lm ڶ_|TMm3 x΂p>4XK \>#C}%f[s+/pp(NRf{mb'Oub- %Pp)=ڳڝ}mJN)5ۯֵQ)AB'D:nk@-*\8v-єJ(nκJ'LϊR% {"0unۃi\c(ymQix nHNPۧ R"~h{$֥gO [\41͛7-gwj8cثM@=)xkjPǁUV5fQ7 0/1`VO2 u ܶ^t͹1dJQQ⫈#`pNs/yMnmW;$%Sn^dIߎht1 ѭXEz3A{{q!]Id  0cƌ6XTʄp3GV1eݩ3UaҤI["T ɟA6&E?/X#}[BzX/j-9ޒMTXvyvI4SviՂ(!mdWd#汀uN *SSK/pIx~+-e~x'GќOLwVU B9h b( JUTM#uԞQEFA@P@ FnJ(H~~xüag{~^{Z{ 4׾v@Y'qŌMo}[{jm\\sӞr'Pߢlq5^#0ՓN:,Md̥ f8t~vKs60/ה}ta U$/LF'(+XWbu#?}&zw3QJx uKJPFj_tohug7r,V2xJo]uER`D9̞2O7 ]=/  9#$HI?ߋnȂ`<1j$5 N'k:RvzNPy]q{Q?p_j3Όӧ-vg=>3t:CU6:;D OXv[J]ɮpڻ+{_2es2Ѽ2h4vxӛtT`Z}"f\L?痘tsϓ ug}hf͚5{l9s,9AE1r f50V6Faxh%ӿzlPЛU炑e #@zu`ӂJM]VE/z]^{/VΆFÙġ-fpAED~ t2x?m? y{JەhE.˄rWv>Zۤzm@? N:Pv.l*y0o[ zE9'l_Tݩ͙*]w]2[S߶Bo}/忼/*%geyJwXǷ x6EIQv?ϙs ޵+\rS +OVmf4`4$v8;nw} '7a1J?9͍'[P!$Pj=iѦ2X^[k4.̔D*)e #5,u++_\NJ,J M(/bB2Rn0ԛvmӮW$̑xymiܼ^ xy\$}gb&W [O^~m N6_`)$wWK@i)9S52Gt92%?ٌf=TCAl)ƢHkI°MdKɞ[] j°]B3s`ʧAR@^n?/Q]IAr.김XiPu4_NvC깇iI{o}vM~ڗӲlud㷹M^~f{q ovB`[Dx1,}% `He/箉s(]Lt< qڞ]jtT<-SQ ^VwHCsiy렃^F^Mw.{lA!ʒs:Y5+@w}{ 7ڤ %ŵ&^aM7SO-1y}`( >L>'X;9ǥ.p [2 yM\e/4Su;bΒ @Xlfgxի9∉0&]r[Okt%W`c%G٣_rԦJb-pˉjjͿ.{6rlPT8\S#1;2_cyT 9on0b.:_m`fդX̟> Iq=[zK%*;ʒW=P2f:z#J@҅ dUn]5/B ]w)g͚uW;5 \o[,zKȎ3K @lZV3w=c*:fG{ׇ.y!|k_udeB})G٬',\̪ J Ai!E/ h ^WJ)x:Q/N;E:};ߩ+1J%LgElŖxzmPQ'YFC`C#Rr]ZeC k& "%Ya,/Ἳ+;r"R| ׏|dm|DߵZ5hD6g\*EChXZDf<<\8@x #2ABB}aDg`/)hm^H@Lc*ݖ/7WKT^\')Aok@9Sz.PBXv2+lki̡ rMS=Sy-x+}BAq":3 UKGAƇtn8mVK币<ԥ[yx|(B08 ` ,zv|]'Xg4C Ŕʝk?#Ŵ ,kZ] բp ?El]V!*쳷3q*,)xK93&VEˊ8x='ʲ^PXIaTYE;B:WL)  `jwc^epCVϼf8E-B-8* w-p&`򽔬z){$Wkfhp%m0_W  /ʑ'c\d1?z̝r4D'}7i}Y`ARֱ_p'$4n6Q3@K{8FrЏ/q5ߒe?r?JHn UƞCJwIsD僁rxs((hL9-;SO=l['5T>m /梊ڀ3 J>v:0q 3L#LIڪ:0C# g\NF]Uc1e*Kέ=􂹻ڲuEpڊ?F6u*nL-p4_5tu>>\8nvKկNi4D]/ ;͟H @iiy_Zy e,Аe]`!4q)[kg㴚E fC9yW-Y8 p->ATOi9BF ti+^v٭0Yfvv^n~̗ LEM;*wmj9'\>UZi[o ?`b!l<л(XEU~)ّ:xጥ9CIE&^:M;l-j#E4|8L> `yiv7s:2%8B,AJqj{ xEuc'\,}K^&Xawe5?(:wnZ8V|V6MF=lWI0A(9 v{BL jhWt8Q|vaK8$BD0e'k6&pv8j;T5;s5ss4 tKm J,+_Jߜr)԰<FiuĵGvڻU]&mH5KtS-jD%i׽uMh>LW`jͱlhX.@9d–z`aV$3f̰ ]92&er/״ilj5||%s\~Xqۻb!!D߅ohl{/~,:8h,@ּyRK%j:bs=lQzƯ/}iN Pq}"{'RA%6;Ax|ز Չ(rps¾ !z\K$aq9S&7\D{D*$Ɏ0i*h\$s)r4@2/nCe jH%M/ Y={EQW{J0\6OKPa_Y>[RZeQ /B1bZnT#g',3mqy-pWhm6h0-MO( ,]6o;rx-(G}tNh]g!:L70K52K *}W aÒO2e\A&z $F$p4/8 -OZ}<$'s)yX_ γl]a\s|GnUL@o笽mW4V(? |]R%+Y:HҦp9-Si WCkaUZW-UU*CV[mfV2.N>ϓ< <ƕJ _Mi!Qbӻ[ @sil@ZGD0Z"< ^? ^e-uпMW}`S:2e*`pf[^ruB7WsxC~ 7"SQxS"_~q&vH75!ݨo8D.#\Gf5"m̆SwBߦ 8V]L w饗vwK>Ͷ]KRN*?.0v] CSSNAie72%+}~3u056b (":MWi>)rwU7-\}TGz)Mً^{nJB| OIfv 2ACe{Xm!JBdgOZʯD- Y l l a+]&;A3k[ SZ?(묳βW^ybcJef4 Fp9sY.h[6T9(oq u1޵׾F4j>F8 }Y~y%*<`"v`1 OT:-8yin#f?jzZsIһȏ&/D92fUϿ=OwpT)l""%k%Aܲv`xH۶"%ki]ꄸd+{Ip-sIqs›q!9w !޲c~Cb#/~L4 eSyKUC֭M%{ Fhȿw'E4O~gO"S %ԏPd8a&/ZhണL&h r X^jeT4 q^a%ϖ%[$W] YqM(-L-@ՊT IkS|! Ȉ `ԀT$;LkbZ'DX+::&u6WD^Y$ e.]ST_7>ԗzo PH\Lͬ xE0YMx65 :C( ?Gr|ko?sH^D04O`=hуK,Nr2E uӼspnqѦnrUW?W,ԬM s?_"]&?m~ {{g6d]<9H=OW Wr \μ[Fn9PuPzL]ϡT OdjTq찚T8A6% Lr>NA_αkES| )Mleڬc2!T+ب0i,`eŮmL<:o a6wWe1WXп;3*i:Os|;3JN |N^9xT3'GH oxñ[Br4_]TMO՟'o6(1hU?bv|].R駟ϔp'{1)&V> \,^]Xtp'tn`/R8F$XDrUdmΖJ!﻾pϘq/U>krY9K/jm TyK8\yddړ,QkFeᐹUhjXHX3K`/yK%\ A Fgg3 !]Z\Y 1.obY3 ?d OTE 5kU'y衇s1d(OG) }(YޞRUHeH}n/ڗpψ9YG6||֥^}e1[._krȶQŜ0K,#CBxTV~̙S]4~媫_鞺@` *OSDF!ۤ`SMAо0ZbC?R?"{a8Ld;+B1YyΨtw}OFdt%袋זY.MCϭqu|ڶv8>&=ڑԈSN)7tcb4Kϙ2Ҏ?d˜5cBPl~{[6"pW^{oZC&a8[S,fl Y?`@) Co/r7t+PY44os9⯍ζ{i4w߼=53!u% M7T+?? ߠN.qNyq 73Ǜ-䦘$}nr^7e /d2P),jv@Uo|E(Po)WonLF?{/Xߖ>OwH~3{q%A9{1JE&6{crcρ;B?lw92C_1n?v<9W)8-Y+ J+LW?|[Q*r9"Qn``‹C+O[&8"Fˣ[b4o/K҇a-@uX>.W9|WGY&cY 3L'%/;*BQgwtOЗ4X?]f_ LU%2ɮ+=s;ARR |_i] /a]T .n7ōz+-a =T5og<76؀xB#(mf̳u1۶'F!+:,*1 vmxFrC(ntgx?7V[mf|~8}Х>tGL)Fit>x'҅Apc2ĮaKWqlzr24Y~+FYi0.6+_yY 6׉B_cZZXŪS IlfuewsmÀN d;$ΙgIQrn Ze: Mj ّXLw5/]<'guo%=W/kg)"d^q4< v{lT tḢ+^opw%3!5,RDEFt=$0q*|ISnNKPݙa'=\JYlu q5ٳ&䊙y3T#\P BCSGߗH+eN jg?9|gl>>林Y:Yػr$;|hΝ[hpuGԙ3gΙ3g~R-Kw %)R _L )ڒX^|$`uIOꪫL2PٳxpJDY8=vm^ą*Evr%bʠ+z)]WԾ/{NtQ;cƌnmoCF,&Ѡh lw-+2AAtWjt Rgݏއ81ⷿmT|mXnv%Ԛ!-G;}k>mRi;@,=0o)#Dd?ī[sM MIklC;El%U7`LxWG뾬[٭]%hNhR?,~}S@JAs*d/ߠEtH/o]@/Fh s94ꛏ =%l*xHxNuwssbv{G)pRk@cO.[Fa uCU 6Xu^ƥݝ{{X&R؇̀mqB6A s[n%0<-'NpUXAa:%')]Jc|+On&TP!GJZ|s*h(dCU& ,k.={v25$Ү(D#Nd,+LCXp"*f4R'NeMskVu5$}B· 7p̌~pmZ;3KRhvg?WD}O}ݒ4>c.z`? f}yk M'YQ2ˮꄲvۥ!۞z'OJe4p^ 2/\xrm 9ZVPt̔ZwzuׯlNReKzs*RI.*-3@Lm3$lƦ[bՕ˖=PVpW'm~C;QW;<_Qn31=8glP.]w+WV!?Qn ,\r%Ŷto.}ݙrKG`ԧ+bxZk܊h/W] edLenLH(Jf,>bjq B/r%%]u9[CK$X˙S` 'SR>hL[y"ٗ R HX\,WfBjµ1c)]O\i׬/il >}yfxp?q_ɰ,8av4K*J~dM@ UUwɼS&5F7>8"U*!Hnu|9~m2AHH=u#&P&wQ/*IxP_.=2pku_rĕǪ tvʖF𔂲AĎr]Xr2X?igwQ 1MAU?-M x/PKމqߐr5.IShp︮MZU3ͅEVgn)ĖKPն,K-SYY;D;uyE4*2ZuFfB=f2byalPi›QN)}쫲CA`WΞ=gV,8=J5I?r7N]iSN1?] \G?Ÿr_~<ݚ eƯq.SҌez`CD)Yl|~n*\hPmO4r6upWg:qT<Xkۗť׼5'|~R|Y>tLxf-"T_Zܴ#{3j:E˪u{o lU?餶{C=_b)sFNyww\ࠝkڃOl ڃCAd#O{ڎ~q>(͕. 4eveC\ ^4,kJx.2enp S:ǒEN-ంF4L$F[o'W<'~t,+HƨPJjUHM7Τ{}We9 4 /bfj𿚷ץ |u 9G: /|zC^uxӋOLmnCpxfu] ux av@0ƛ),WlVe=C.S^6y+76`Vri3qɴEuanBS18y3vCz8*ؖz7>묳^ ) ~?wu\zK 0Y |%?mޖɅuV NS*nyo?WwX74Z dws~P2ǣ0Xx`؊_A맼|Q(kvלanWd Lh^]RSDHFEF4s3m\95׿֢%9r+<i;.3 ) F|hDz]|/x tejeG?{_:(p޻}NPl /^\ nߕ; U95}=[otS ŨK?nm-N;S rY7/{MBA~9(n$$:aBJӗmUfNq:|b뭷F<X\ΛwḬRwEEE9aVn-DBV6aʐЙhسt1f7NxE ӻ1qbַ)YqsK73zܣ~»숒"?\Ψnzէ9rJ~cлytM)%a͌3;ۻ Vy[{㊁[dCX~nsdiq]*xFW>k-雌-EѦpΌPMY$և>ȕT2s\#@̓Nh,֠$3Ǫfr-usGUBZIj9昊V#yf7BM<ݕ/ GgPQo})Yt~A%J:!dKdG$= Gȗ꓂wd >wm,Jz]91kGRRADJ]p%1aR:.a҇/=lt2kL<ռоM $R*W0.BUw  vv$k`wVYeBA2`O<>ه> -n}^-eO?%^Ĝ=}@٤+$>02{+f}@K{^NTՃCt n0wlfTsn`-Á%&*9U/ϓ<)<?1~c]1Y拋͚54qo~ӯ>{ڝ)f:U.dys5q[Xb&c_T,mGߵ›_xBE_yp"{V\qq`+; ԓ9` c)BhFKNkgSbf4o޼hIuhr&tc{L¯ $<dMp1/ˤqiywhUS=f yaq]cZ`֊ ̻6,7*#^y*`]7޸Te ) nfEcFF4n I?iZʓ ?T9:Do]uWXOҴeZ69W簝zA"*jF AC:,k u]=O!Eӄ|[ Qr(&*7N=t#G>q[fȰp?O}݄^z3Rehl C)# eXo}[=X;?!S{0 ~e6v뮻_w *w( Λ3fܤu0>ʉGk.h[׳qȡ]c,=JO ,za TMs-MJ޶-˿ pG,&cN%ɻc\hJr#0V8-35K>Ow´iE%؀6]qYRjŖml_mK7 wCtc9a=a0b׹lT1^TXuĎ0%/O>pU޾c <&rnxS<88>MJ]™d)౎N99pRKX;tIJ1T]w]Cls-!tM7OΒY0_r˚o{Ox+uXX у5Q3sIʸD.w OGWɵ̂stoOjstCGJчr8¼"$fv0F4AF<쳷n;H.sYQ'tRIKS gƌ]!nK8Wsc(w^9B' U>P4.TdTV]~v`58zei>2& bDFh":cCkrԬ*/!c]OyˣٳgvA bİN;Dvg~t/|h,VN3)N:>)zvp6V"?D)  rM+ Rnd@^fZUEl"4M=ؠK-ЅbݳM{_+nFbvc.%M2;l &Ƙ XP3䒉K̔L!Ѳ`Rt3[H;\2Z5W0SNJZ"wSUIfRn۠Oڜr)Yv@IE3*Ry>ֿ-xN8pKfX0(};M>IRmnc'eJNs~mTI+pQK4vp.\x~6m <> fi=|B)_cg_˦nEqhF0@Dp$2o*_ xu .5wIΛ7H:6u1<sMWxWٔD4Yh"z֚ M7ݼ;?q!ScYZ ]\e*^!*f2p;cZ!53<ӘVS0Eo鄾񏿹z`@\Do%P*s4N'P?D^y_e70f)UJZ"X"lyk|גeZ)@ 0cs}ԭ* I~*v4X=y9tv~wV/7wSNyW_&/]L;E{9 T h LVW D$څCA:Livnub6]uؙ'wU@{-%ИׇH;_&2*o/7DzQҌ0.VE،h[ou)ʚ85K/̢_4y63ܵ/< `wo k[rMKW(hꭶZռvy /s84 Z:)uda,o|9+]VJSm6@cw˝5*X2ǾrVј_1b ^Y>Cc X+$C]Cc%6܈&vt_m'm4H԰5&g?O5:ƄZ%/nPIxl$Pap \.kx@|۬ {c+3ˌDiMh!M-s[m曟qz돧NJ҃nA a:Z֊KGV4 ȩv KNRb~vj,On#IeilBymUa9ӐM;Tޕ3@9YзriIb.ȗ,]_`"au/3mjL= +&g1cnB%55" /5)9dL[ JLa#KiY22T[nɕ )Rrw*ؼk֕9$I%jڻG. %lWBuk` =k֬~^G~t3G=2L]A*z>a';Vw?{?dfM{Y3N g ' fFufJi3gB!B@B5g-5Uhd7+T zڷ('+#zکSLMEdM`[ 3[mޮ_X= -FZwYY-l%6fe+2bC|=m"PԵf ?U?]Τ N,%P[mO!DQԉ ҶςX1P^z)P}stIyչ6nZn`̡цfDtevo " ntlڝG|5^{aV HEpR\MSO _BfQ*g~L3Cc>zꪫzS n7稴tØ8PUWdA#D6_< *vuJֽWs]ϒ{[zK.ӊElI^l3.GRF71Or9X̙3}_lQ(C #׀aظiO.$hi__ٕW./IAmֆ Km)t7包[S+=]X彁uRVL~Vd.Q"ӧt_3zHlЬL\VM&( PNK*W!dI`A5KNAhI׳[d7eO߀Q6p+H𙖒͢x7OOzh琫Xɬ;Zח7t3=JoK_wpȝռ2(w1Zwvn]~*!ȫZɕvذ8n3c=;ZM=su+0nV/aq0U0Spt (aU(ZHn͠9K(zFfNsbF6v7o:d3kߨiKkgb3`B/^5F֗VM~ )M_eei\!ʱ Z/" 3%vmUi9s"?x]]IONn?ƇjPf{;y1z'xbz~/3<)ߗY{F[ۿ{y睇5@nָG )Ӟ|059şi&zsԽK݀{XnY<7AKXq+hp* ׋+|3~pByb*am4 WR!Գf̘l͸&c*4$")ێ=hϖhd_X@a3[M]gz֚/y:2Wa7; Q]6:OlrAmֶZʧs7%b\v;ێe;:E|JcQ~Q餿9s>oh (4 6TW>'o+C X,tӉK.)tUnCci,O?w^^[66N %^6- :g B` o7y2D3~S蜛fs%R5[H`u5|ALvm7T )&ck^x!^Sar4:-𥙔>1 ;Bgy|?UQ5]M|x(O\q YoxKR18pcuɴiEn?yA3l_oHkC{VXa3g*_ gRb2ߩx;f~sB8~VYe=0F''DۙgYF@HD<)E8xHa#_?9!\,R=mb)SeKu)aEfؒfweN=4Ib"9[J[^]; LDg{?G_ݾV[N]iju9~}{NB2)r~GK.ΈODaSHm ~@i@P8GC{½ N"ֹ ?Zotkh;VYy7_ u92LIQ< \{b%\"hHKq*X/Mc]ҙCoN4WkrK(lm&ӣJ6LtX.2 w=|%6Qt巭4ˌH T]?8|wyU+%r1P?OyA=X UˊXr:fT5t\%]./?JA5C}Z*S_qE.lE +B\I| 6N;g3}S d^W]uV[mYR?ȣԛ|L3d =[4̼3#wCםl fY+!4ŢgzJs0#*٭zEeyr4-c7~NX^%2єjd'_uIA]׼ӬrYD2U%m|q[[jrMf \%qH&jm^<ol~9KXT?|:]z46ARk뭷.yQWr^* uXn"H&luhS|Y6Yҳ`S Q*h)K.sr-sR^?%ʘ_w쥴C{rަ| N?V6vjeʳ@)@,SoKEpfakov1|#cl+qÿUNyO>dӬKV_}VqRCn9PQ:Vx.U *Ab4NVmK+5~{~}ڦ6X}{=Aq'IdM>lϓ]c籔 ! 0xѴ']1}koFbӧOʱdxliĜpJ.1rUwG %p_e3Cz1>ObJT{"|q~3;8RO2-k5zKgΜIVɔ7h#rA;cD CHQ O:OK 8-ƻ~y .ӠB刼C(6[ SYiҚQ&.niǧJtYgov6;o޼*nt?^ $U :@u .b-K_J[WZKeFD eb+ݬl,3Ĭd%K1~W=ևx~x{qf^#oK3[ё&BT[ Yŋd0iYgg r45rHW!?@-rLǟPyxexL9, 6f,^7tBD%JɞShlퟗ[vGd(hvhH83x5k~0>9[{9Ѣ;8[r%_M:EϥBx0s_G&*iV)`Eȼ26A?Eڂ[>(Ua4nuQ,^[DXVdx ;Cz.TZ д<y/~:(핿QHa8ezK{]s逧UKmw 5 'g͘]N2x=9䮹fe^'VX^0K^V[ioy[KunZ),:8cj=E4P~mꪫt(;-* q '/;CL5T7_ t똌R ץ* jԸW _msjPfoXQv\Q{N'EB`p=L>Ͽd~Kn@V[8?ACΘ1×c5Naq$=Czg}myѐ@_nH${`ǵ5S1ц ~(.NU>ϫ}廾p/]a4M'@U|g[ ?6l1n٭PY& `zhAMnu[RT# %kR  GNU2nv)x9E 4DuVIܠ撲g]n:o5*z/&rv WZq1(+i*Aw@2t ~Jй _O?b,"Fgv%`r--psdئnJ+# (:Lwk\lS9s9s.MOu&`Y͚hF%nC -G7$P⒐ZfaE  tKs_|q&*\tE;vQt'(!Vݦ銰shMe 6AD%d%@VRyaF7_%~: g|R>68k-: #kL\̤K71ٳg'S\K-Qo%(MJUrGP 4˨H^[AI)j%1Φa wsZ;q?8{\w$!*/S _Z(SaF첸e2( @Oߞl+q39 Mb4ԫe^ًڵ.BN'^@y]!i""wDLy^ qHr&K?kd[HKP nˉ/zыqvLj`5ZUlzɣ)3Al n2$ [ l`#_gyQG-G͡;-EL ‹_*9\辄"3a0U=R88h^S5.&d#6CSRDkp/MZEN:)s وfb|S_f* WޥUu3hoƩSjC2#a#Lc.T>~pZ ~Rl4;_" [IN)NAIar;\:?:_ V:~r_tʳN6x?z>fRU{ԿlEL02Qk| A TVɒ)?N9. 0lm[G~P`۰[1M`Gy'?IAei^6rL٘Ѽt^[YPYJMCg|Rb-5<V䄖3h`q5뱗sΙ !/q%oMJhAe|tӌRw|T%6__q*ڦQY -POFOn!WDKu\=pB33wČ4/#VV\J"˕_oqAod]G3?s掿|-@dW_[n3{KuEv4puHYСUdiK{K_zUWKwvYQ*Wߧd& _N~|AU>X<-b.ԩ[uxT/ bVw@*\pAG0^E0)K׾?ɝvԄ3 qRR)ocۊT#`WF09f멠E `uW'&*@,@ɢY{py/=m)D­]jR-ZiTwU0Py& uKlw~}Vew9 6=|;%HCYʹZ-*5u~w ֭j Lgj6"7p PhOFDmCa#nj-]tѧTb*kcz-8O;m)ʅa_mFoL`/yKB{Ӻ"&>pe-(W%KjL!W,&3<ϓD s]ò.yΫ|C|̛7ol7+O,NyZBU#(V&lqgӘ?I^L[՞Ј2YU緍{駟^41?paKםյlɓSv4$6. .?Ps}.r, Ɉ.s/uoQiHw8tqǷD{QK/ W K7#REyZ\FY*g?,>X_B0qwDDpIh(hL?j=e~ zU <ӧOtZ`*auEfG:HK|vͻ;>>ؙgnq[O}ÔgD]xKbctI@rtk&Ŭ~Ly&J8Kv.٘ qNwfmJ{#u'[_1W3;3J#tꩧVRtW`ȝ7聭*Pb$jڦO@>\YLnA 0bPS.Jufh1Ƿ>;c:%Ѧ^WqϗF)AK?b@zˁPq`!C/xl| j"hsym[£s:Hqr4 05`-A8OCgH'Pi X6G3DX#;7[["X-e @&Gl%CkXhu||C6?dO^b_cN8NN7)9 :w"6M\]/VܢJk}D@"ʇ KU`:?k^Xklz#Tͭ8!2\r8doگ`+Lp41;0aC0ͧ C;8w֬Ygq+`T?e$V[gĤ@eo2 )DIVJQΊZKFOd`@ V_-i925fg3uꔖԈ_Du}|K_,_ >DыvR=p]/z/>x 7dH|ͣyǯ(G畕Ѡ0&i)IO1㎧Wn?,RaE)=Т*Ц0jCh&0G5/^wsb‹WYez̙3+Y^nD;QY!fݵ/s vzfcy7ԴZ\JDZR唨;}¤/1mVo_WB*\.]0`О!2Jt%"гώ 41 e3(;]Ю|QjdW\sZ??v#@6.B[FM}e؃a+)]š ٝw(Ǥ:rj LZW *Wjp<>~Cm&E0gs )6!iZk B?d'L*5h L7Pn6(BTs:*FTNu IJM"QcmcV\q*4-qBҪ}ߢNzw=8#.QHln? b"(S@ #8jk]۶9Zk{vN*@HyNd(q*Z<|qG?{ֵֽuk] E׬9!Uʢ4 <3,RDmn0 zwiW\qa',kv&;,ªU #=W\YMr*m '7|s2yfNI\vЙ#gQP MpgeWȔ+WG9ѐB ,on3Vrl&)Ϳss޾gqHZTT tN] rU3<B isxt#t \3U+HLyu SXYqǹiDU0i!2y:>z)@DFg>f^o,I]'M@)2:Sc֫R()ӧqJ2߿?ֻ;1D<3^ Wx/mQSt9Is7Nܾ?3L}i![5Rue%Ω; ڿ d~4%A62U˲eεi3vDhӲ?Q'0)q;nVw9[HxJewS&`nYJq^.dЩ5JΛWO 0Hy婁`_p |<$"|"͌%\t/Uzu]yCs(eo&lJ9K9hURc*2;{k;j=^Ty\|ڬ,K6m}j^Cή{ô{*";M_xbdǒSòt؝ RoMLʤ+}z4N%OmGQy;ŋ/`*0c2m,Cۗ5+*M ±?2k,)ce˦2{WSwHuDl\jOf7o{O8ygy_#EOg. . #\rI@~e{V[33bUEH Ar~.uBچFD QNg7>6üxSfVKڟ?L8,5s*Yd턗 O*/v*bB>k$33o}{u@{`F?{׻ũ|ϝ1caj~0 0׭N,Ns7O9??+ykT2cVYa ,[o5Icz"Cv?蠃.< /oew2޿V[yРY榎;] 64Y3unY=!5Ypiykk4wS*&iOiW7U"BoOXvE\o?E/zg>PJ;C#iKFkO|p(`BdºܚxbŊc9DTXtuϝ;'Mٸq#R OP‘_G<[iӦZmJ+PZ^td)IJ;< )--R2TJ%HRq!lRب Jodssoxƻj?Ncywy䑟Oud=/)[I]q˪㯡/Ơ7e- })hPK)Írj̩D v. W` Mt j?tމ-';IFZ(һ>)2)?e3¿qagV%*׮X 2|jc 7jD^R/]VojܸJjv`?Od~$"ɚw)؉$5ʘI`%!|GH"}MoM;/R4M5\ir7Ν;>_!xUIfͫ腘clUMZڜ9-]o4o&j7Zaq]hIM@4r駿/86L8 L]WQt)jx&[A,ػ(z0(x[Oe FS))"?h osWR螾2;+ Fs2jY-{"?iJVPHTD?mr(f^oY=FC0[C.6u \_&r4,\@k\*,K (CآkR/XvmjbڕW^Y^?EO^:u]ꖊjz/]wq3 uC^tBpES_@źJhmoY{9[o=?c_&tZ)q}8C|*|sh"K/TkY,X~Sg1Ay睇-Ew}m)÷e\ o>BǨ̙o($C8^@rs]De-;sYgIn!ڰLʤLO_ٌϟqܝv:Y%&,mdU0+Ŗ٫=iKF禛n] myvC_oWg)3iY,}ۖ =xΛRpGAv _6d3{>L 却,i)ЀT7nW@back9:u]M$:}&L1 9wEP)!`kL/FVğ?ܿ! l7@ŵoM%JVw@=O,_w|?}{=;n-V]XH|P_ Hso9gӑZӦMس&-4" ٨ͩl y1c=.ŒB쳷cљͲߖp,C /xU5k֌FzCN (+{``:"G^UjӿW>ꨣm/.Po)RimX _vd䛓~d=L[e34 ~>;C{%xYc5iN#ibh(bγ%#6= "WeXB//.[}dTl I^U{oKbE]gq~ z ><--5vF(KLԙ kT`J汝 _a޵4Jx:0o&̘CII).7g8ՎPӲlQlac׽vkl}RA$:6 ̌?`;sR-AŹMQ0k֬G]_9 ~ 9PrW[]r:)Y4;z+]O=wk\lD@ R:wlr n)"/ s|&b邲0_D:W_}fO^ֳ߹|#Ib[ x'^rʃ_M?<.p*.=fo?^p(ZGϹ=yO<%-k_L6Σ)mqBMEٱ\'ixMB5s /'B*4`mROҗDm-򴅅kpw۬%ϵ[(b\7q my*J) E ^`DR4JGSVt@?FLfe'+dLD.Z?G}4&[`e" %~ҘS8bҼ:r5FAiivb$u[/?X¼2t/074L 16Pp*Y;(Mg>{,Xr C~%-c ڰūKP[-0N GY^ի;s;ChIIwR6#{[Z# ko 6>m6rQ+C$r> >fɾ;sΜ9#&T+(peOw}30KX;Ssis~gk3̓F#'u]sfO9[!Nooq3n iOk2`CI@2n/qA۾1',Ip +|ĶrB6d  ֮}{)CHC9d@˓iEgPiv{{^uzc~f9 5-G쯧2'o$:mՔNQѼ]& dɒtjJwac{៞(# v/Ye],$whub,}c ?) "=U6҂te˖K.Sgg9G.FN5qYNG|모Mk!.dxYx²{WCn 51fk1sruR|wIn3"xM5^{VT qkSUv[nb5ZoLʤLʿ߻~GwrY-|Z/݆Yd e/{ ͞ra$::_%[oN(6_Mst4UCpMclv^ Öc!Ô[>-4_ap(ih!r HVҴfA.ō >!4jƌX#fc!U۸qcŌMG^e]gռ_xG_X:S{)qT_ vn=_7vu\zӧw37iTlլ[٪+<8{,׃?FfKRZtƙ.]TsuPdaedZqX0aZH 1VY=4h*v2]`A8  0C7;ZE]XpsoYpax4N> {Do+5R4X0X- m94ڑaZT #{ &> Yxd!@*ӝe`2<6 xOxzֈ KIŅx;L֮]`j\ydk \J`ӷ Ī%hdB-: Cm]7R#MiJWެLʤ<RrG8}~[Oݗ%Պ`B猐,(~F-ݻ8;R>_&dn(#/xm[v$q 6c3Ao vg>oT VI]Zwy@Ig sL ]~=n-;w-ܒò: Cqi=Nd!Lc]~s , 푟偧oڭRM+^ f ҩrxE &:Ǭ IFˠ-$+}3͒ÅhKwV .lӦQfqo!7/,H#>ZD=%Ƃ s8~~"뮻PFl193gNG3^ /@(f1c ݬ2pnc P/(Gg [aIr(:k=C+GLG?4v~p7YM'\\Jgd ώO< /TA%hбk']!YXTY}C˝&-?.FS!Z^dIᝋVjtVQA>~6'Ud"JYAt®& &&؝h.i/_f\Qq`_yf'eR&IZ6/{pH[[gu1Jxٙ8B@KOY|IP!2J|۽YzV5X2^XȖ۷np ѓwzѰPT l%}:O2JTt {s/@f;7"UQa 3Ȇ "; ee"o XAP_|qiH=R۵krS{bw(WC!H)'.3?뢸ve"lqHMVunf}UWfNxʨH5}dTu.@OSJHAfJ!)|1dR]vوZڷ,V[lӀ46̚5Xn"KfgRB D~]k8난v-Zt饗v&@,@ T0X]NSyj,uZ iT={Uh]f`M,#SiWKY;dX[<ʱ:?Tp#WYo^@ ժHC[6ܚ\-L}4|ų֒\nԉE.AQOVWJ2eh50/3)قyk^Ao0=}:Ք!{,G0VL қ2;^yK{ѬCi2Bd8I6)2)e¿x %CnTնIwIv;ԭ ܩ?ߝd9HSW+9,TrReˑHiI aOF1M6ECvt pڽ{,Qs޾C_|h2Sm~e\w~!OiWR5Rufjv޸qEoέ7l)7 }n[w5*6y|Ŋԧ?L.^|xW\\u˹&Ehz˖-[bEUf iR$atZZF0`G,ǚpH]S<@1crz'ɫ>܁a35}|ݿkG~0zO 2Gn=9]k9au*Y`WFC`Gp̡[ =r\8㙏]_;C=xT"5u>5dt1LiΗ ^}Vo\~I'͈=#5aQ;8[G30eXTe@!$$xۀS6[4x:zfH _|q'v4 q<0֯_ ZiA ){ -BFP2 /|!J 7mD7;81tQ1 M$aKEOO>ٷ Ϋo^yy;uY+I!n2-}[VW.[*Jim8K^h{.gP#uTjՈ L1r-fV; ̙.Zhey g,@unXnh3}ɐ҈@tw  'OʤLʤo9q#N7n.ߎll}^XD,xi|aRy bvVl̊Aڒ6*PU3f GC`ϦM ܱ뗾g}vb&+yY^R-OM;N!{޳ݒ%KG ՀyExHf~X7Mݾއ'8:g̸Q$AFb`ȩʅ<Ї~Moի<ꨣ~>1YE){W&&f9 ΄ig ]JH%e,)l{f$J'p^Cm4YQ,۔a_5snɺmϗ67hzGq0e{q7^8@Ȳ j+T6cdϛ7ȡc=vE(*i@JASewya-EPn@za>;қ6LoٚEL9Cb;t|v40ۦ/d]wBa}jЊTc/ްaܓ2)ol^![)AKjc> T:9#oЪ}6OM2P*yTN J<=F;!mhD6e?G[1vuW4t4+)@LyK^xN2v@FZ% $ z"lv?E>c ѠL]#&()v < sthi rGUӿ/| 0#|1sZ:6r"wy0N k=ت_H%hPLWauokr)3:#xϲreu?F )udU~ֆJg0 `ѐ亰?h_pKރxѳ gW P!SO5^>Z ن QʘS?e{,`/2tMN5ڷ G$c'u_>OU{92J1HvkZ(FpŸлUoyԶN_f`EP..'~Da6JX% N>d5waJ05.]b؍7NũcřGO+UjOy̟?_; ,,ڤ(˗/71 W: c9kvK-Cy/I)sA0 `Y`ggORN};Ϣ Ůb7m#u1qF93},tAX$:}07rв%S=d#5>-yqߊ+JR%u/v<'J̩ʙע 0 )ЅU0"iHuA2Ga/)*os[c;(]G0*5KrY%k;ڋ@ ;.%5+I'[C|6Xp`K/ n;hզw /g>nfoAG;k`K;\ GW2sN9%Gt>+4P̎zCIIyh-Z* [t)ٱ1c)is=m_җDjqE[qlme7.Aþ5;|N䏙,ME SŋC PWb)I[75 %JY-UpGIH}7>HSB"f4h RɧC RZ({QڈŹsg*AXj}ɻhѢrGq/ CC<5>dԵFPU‰dW7ʥ57jXӍ]dq+W73˘P*wAC45F.c6f͚!hX0sa}5S`4 +rJ3ixÃ~gM#VFӋh:EbPuWQ I:΂R洫};(%N96=j- . !($@:;ָe֝DG?W}ī_ DN:}a~.'   y*$*]p_>.@ .1xwQ> ѡU x4.0J&M呢֯_>3J|ϲ7lBkt3׎;CW3KAA,Mx<~-z+dU2Y!T wˆn- hS#*LVdDm) P|>}*f]ΰ֡IGO6Af L^uQ.`2/xaB-Yꫯ#EͥKX/|%\2|juATGY!Xp+.xDkw}ML"̔mk׮̤, QhZKͦCS(sѶ-p__l W;h)/ZrYXr 8-*ujl!=dm:RbӦO+U|r!j^Wa[Er6 mk,㒖_g,T;Q矿IIX6;{} `eOe~& ]6n"Wm4DFqkd+y:o޼b#'aaOD [β3gfmn'>ᒮqdDȖph&JLLrQǙAr#H|z衚3.*$w{_~Fv}Ap闸s %u ¿9e8 \ye۩P[ӷ6F|4wWT޼fWS;pl= Y9딼|РS/ 6e8A pRs E#)Q d-gQkPٚ;)l>GӖ~9)2)IﳳfeM4'cD6IIp3I#n''SAtV l>E\Q㏿|mXݫVޞP5 ЎqHZXphE Vo=vr_LERر/J95I%KEB?ґwy ,5H+C#<OԻ~\Ɠ" : R"l4$Ǩkצj7O:CnF 2Ddqco-LbBE4O>]؍'%)(|\& ;p8k=xS|Mq2Wi,nz Cnf|T(tdtKyX˘j *4-Zd dPYYW[XjsNt Y!c\`^-U˳1@^ڥKק7N%%tޒȨ{OySZ@E^҂GtT|`sc"hsPK1X*Jш3g&4[G>9o;"d_C=+0Tcc4qwy:~ ddFVdZr:B%TV3fhij咣@7˺|Bs߀҇>M}1\uUfVeE[,8l)mn2,d7o4?h ,TDI XR\%G|!=%boي0HGU[o=P/pH)VVt9^Q`SD65|19o~_\gx≆6BeŐFT0sFҔN;O~~gq)rY?_D@-I'km֭+w_쎓2)2)ZeÿwneI-)DXe[f3؋lV>RS GpV_2r ujJdQ+: ?~sѢ&A̙TbX%dV/^p\ੴنAeZdB%L mG<2Ѕ| ڱ&:R8@,_$r} ] xKII( ,~)0 8AvVdAG:1hrEfT;)9N h+_Jִ5k:EG(gM$fٗQBfȧC7  BłeVN; bŊRv G ?pE{#<& |8P>Bi8x/iѡa ??KMeiV{Giyt^ 6d~8mp1 3)Baя^S&}!\_>1U v/I!JJ6:\Ӣ8lS7ްN;&4"n ,_Ba \ƥ 1UV4hKԼqâVHqH1ԇ5;Gt˾S e$n*cEmӦM$ 1>|)!'* -*nt?N0TƘT+c/)#xA{Hexb#I^-.uQ]wChU'oY7I(RaHSh^ 琹 "`ٳgλFڵkax)GpJWP pB@GDqƌ_}ȴLKb ŇAyѰ# -nͥ#u 1Pj=L,h};p i=8_ [gJpwҥ9K|}o(Xm5Zۋ/^n]x{_SSمMSi__F:ELs4w\o fVsd/tdep|2ⷠJnhvʕӓOCj\;Y}ekA@;^,Ax^z7szP`Fje hjʛ[@ 5l/iӦaho~ͽNʤLʤ?))_?ߞo!WYCDh ʒ~vMvYn"d%!2nF.Nڽ'< + oy32D[o-hX9ɵz0,Ƞ)!ODh#:%QkEy=5UD^{m Ld=D^J, KJ,v2[` Rx*Wk#;w.;آE K=-Ѡ'IxЮ$_HDZ9CٰaX Bo9A!kaooI]v٥sI2`7wyY?eC%5']ku}[b8^xaZ?yl/_uE`F0o>?B .}1 =_TC˾䴋?3g P26m-x6c ^&b6KN/1~uMu]irHFz)zr W<%[m55j>hr@ŋ?O T.c2Ӏ{HbNެ}K@ –`b:i>7d!Hiׯj́ 8o ! 'ggfSW_go~IvHOe#:5Wǰ m0)0ٳ˱5wܔB'M ɲ4KSRAf|z dQƢO'~g(Th"@hZh0vo/Ǘ-[6op:'?kqBU? gs0Q.;G&"9'Ss!@bUJWU0Rvn4hF]h4DsERLMQ5>vTs"]YX6ƅ ^~ j**1*FwUWrq|lNYvn{l_OdNxbo͋ɅҶenca0 .+i]ScN)~@q`avYRnk9";fMde4fSBgQ@sZюWׇ%amC>ͽ5NʤLʤk'{H`7I؇-RY2r(fܵz ܭl ,(E[tի N[RK&Hk*' fc )(A)4ґD>m6m* q!\u:ouT8#C $52sM-G$3c'%1 @8\dk7ṋ5yYg~cas?qgڴi\p|>20_^{mB+o4N4R3e9 z\ 9NEVG}dႅӲ բS`F=<A>*tlڄ Pjqf޼W>8aAZ pb}RZM} 3l?+V , C7oޥ^z'k^|ID q/p(Bt݇F2$d\JTFl"E*+>sUW%})Qv{{Z=DĿd}e/U[nICxWzfr"xѣ<nڠ:}3R\9dA`WwIgg}QmopSNOO)V >V[ds\谫p7Zˣ,&! R)x^1lcjXH6TucZ ̖"O7"M}${YC/\P/|! z93Μ9 Y|U _*t"{&JX9T ,E9m :i!5 cW 5jP ӵ` d; ̒sA`r,_g= LX0[sݸt샐=aAZRYu{6m~%`/c=L)xRS1Zڷ<yx}HqM-0;I5K\R *nv35c;O<|Anr7^"k )C̓)lsvZԹz10 ˻cb|@UD}k_޷wIIV YdɺuޥH2~gg!%TLٳgkP~v…`PWmS~gf[^(`rW//q:i!L KKyP_4s% |sQ>1K#4S;0NU>^<zq"II " *7eQby0-7~K_ҿz_|7=[#8br@0EiyI YIQna2YroSi,6[l+JT4kwDB/ͽMʤLʤ<)ʓ)-]j.1QP!y ]BX4u%rt U ՛(#\r䑿Ok9!8}KpI\.+"6k3R /jhD}x#:V?ϪF*媜&pΜ9_~yΤ =d1GC42,$BƵ{{^}UKp5s 9{?b=F cFVy@W x`4ˏy"x㏿뮻L&-H7`RrթlK/+t֖\~3e2%4|,q b5bV3^g.-[r+T5fB5&}%=Mā bueh}n|˟{\:ZuŜGOf{i 2 %pB #gO]eVHѐ^TɘY|og}:4ϛO7&XÓk2)2)?Q$vX2W4$ J);̮iӦkѿ C'. cFSi:zD| PP%@Rh5ʯpfɬNJ:Pdl)d#:4s- iE/5R@`ԾMo $%U@{.JI{0!uvQ (QG>hC'SFq6q^dHL+,!o 2ؔظP |HmB2V\ve6d8W!,L͋~D弪dZb(lfZ}xM:NU^B!BJ\E\7y )v`< ͷr veBC%/N{vҥ~?<[ \~4-eѐoEϕW^iy^jcs4nܸ 3櫑y_ >usN,-̐ZR>oS oʔ!:smr{G>Πʃ5U$4uZkXj[,X/ݦ; . Zܜ Ê]~}Z:{l0#ҵ1.y93`ҿj镣,DL"NvV2{ t6cNIg͚0w*sgww?)bIdċx7f yW: m <(s=l{u*8̋Xb5?)2)2)I93gH*rBvM| H R_IRsLwؚ5k4)`"x,+xG^z~qNҺdͮ7Cbȉr\YBa /mHzы^tԝ$/x|R̛7Hdnڌuv)BEJ)/p@ti}ӟNiYΈp<}^4,(`K;&&PGv5VhмcfEq`ZDvx+Vh6;ͼé=Púӡmj@f Qqb[È/hm0{=gٲwzM T@|A9&H/cfD Ƕv,mkssoZ2)2)˓ \(9H:tI^x!IDX?$ WH =Xe7NW+9ھK<?0O;cYh$R:6‘lpMn)F:u4@m49I-lS\_e}qG6̨ f/Q]tZ\veȔN@ʋ-җaZJ oe) Bwq8Ѿw o~򓟌Wfiū9ObXWrc BL ,{qv*pZhе94$E a~d@S9I1[_ij|4x+Naxsza]p="z֬7~K_jQa?\뮻+fϞWo̙ZZX=k['7.N8o, K(Ғ0Z64> oS(2۳D1!]'{t2x{_|ELA6"(Y^q {IIi(Oنx"2:7aDi[X/ԡp1(JA<G:Y!2W_/c}7|3ii&,m ٗ b]F5Wp`5E(G[qX8O;V u]E6򭶚7Nq)ͪƥG#K  6Ka1?Yv[~/xb閃%CЎ=X-X٢YԚ;+̘=yVeX>}z.cdL'<@̔. u̙ӎOEG}ի3P@ vW;.Ќ'9-HMѵBHnMzV^ay'64)2)V$OyT+52{]uU:F: ! Aj. H$|R:l;Jyg&0 X=@>V—> u Qzʕ+ 8wɮ)@(Hp²` #-Vi`˰ǒM@b}p75OyʬnUDBD.1h=^):l2L>Kguoo~Usҥn:Q^5 CyW"$+\[VkȜ:hQAݜ޵#WѠ,~Be"%%0dO)-¿M]&H5ftAf cM6в.ܴ ``u:_ {Gn_M|еՙiѠ\M)f{17-/coF[W2Y}]xFӳJ=̇=qiw*kMKhh?o$zm{CIIi.Okw<+tx|\*wWOd(.ȣA5Q`a-m/FFʐ[D; `7Mʖ:|K@7ߜj+_/| 2)Q5C+Lk&/q;*h@DOCRU3V!xY}m#ggfo~>38f+dɒn P̣'k•t68∔lp_֏[o50h+L̠Qk/bݖw\0/"Ayw,һh8 FOXJ 7sLQfKtɒ5C.)^{Y?ϛX/gq*S˱K@cQb87o9?~q=r$a￟$JgOu8E#> !-rZ>}-r 'NeF~tAECȩ=sv򗿬G!cj 0Bb?SiGr||9>;wnwAۖ3Yڲe=38?\?mگ'c5g-W~.,N;͛XFÁrFP!=׈)!-Zt~SfZO"Jx\uuh/袼=! Y&`f[l1A}>s YƍǑf̘&Z(4c/;\˦(^i0\jL+YNjOMH (*s0B XH"՘G\uK;|t4g}Rp|}M*Dg9b"13S|`j=CKenywv {o_UĎ'YɖmIɒ'1K!amsCJ!! ! $x-[,lɖd,[dٖCNy=7s~sڅZz>{=ZkKuyO1H A$qS7\c6W #Lb ;nMKKB kh0˖`ƍ7. O8a ]#Ο?yY cBkL(υK^Lm 81t=H&qhh: Ӂ ۑ#|T Rgp13ćo< r< 6xTPrŋ-330NQ4WS]OAmhP(4>+VH ϹN7Ձ[ڂXxpFϋ$:ŅV"ݻw~`QDWәA}Zp>Q bek&ĵf͚?ojLUjzgLH́I>0f))){ c}*++1#h94Q22"lU4 S0a<B ΋/Uj꽮a01mi*귂=WϦ&uj˗/Μ/y $H]In22hW&~nYi… ̕aCgR}@dd^s6.m!V3aF3 )6UA|!"]@Ǯ QL_ӽAEbQS~u]t)d&8`0yХ !eÆ T_002*LF.X1(aum/&w ̔TZZZ__ܷl2MC3IY&bsyhȔ`:L oӃz@ hQ%%%DLZt)FЏ_&V1j'c@Ln㺶hTX==eb ^apÇ7 `e"*`өhy So\5nsAl+x ܄/ ٓ9ɔ9h!.QQ--OdghTB  04@Wg"0L,^w/_җ\w2ӫ;:n@F1^+=V.t6o,:/zP]gRO ;oqT,&e }s䓡EC1n5kl۶mƍwhԩg-C<УGONNC 1:^)D 3,r#[7E[;w~2^<իwejiɒ%:u*1ݜ)uX>M{l4%:$+FBp;Ah  ; /' 45~҃7_=adқ#J\k k.j)óepC;hh7H A$$mp``dBa.cq}=\fRP>YhQRR3esΥ(wr +V02c,,fL@ 9rdժU/!רdٯܜe۩L 9DF `H3p{fqYy{z)#r0CQPPpPd(1`/Btp_ahllEd]3 )oR͛73&mmmbdZ;<>ӡacjAу1U]t\UUX ?W @nʁ^T9/@.O0A{2F11ߏ6e IX`!Oa6ȉbAC?C-sWXt=&bAqw,@g?RQa0CfVąG*N0:tTk]}"pEt1fXXvyFz^3{|w qu)8L=iii&_|衯{yo2cѣyee ̔P͜5%@A\U^F<\NZם;'N4WL- c^\\L=t0<,adW>˷m0 $ȿR >B ŋ ;?0](u8q9 `JX&u]a.=M qŊ/g$ɰgΜ.us3{IJҐs0gTzg(c="-b=dMy~u-[ 2>Ff~=Cر+܍u XLrL7^C\hÊb*HP0HlHg?!U̖3@t70>&JsŌ9]3xP.Uc$>/++kjjⱺk2i 3x wux;Y:ZOXdt0cxyP@6Z#sۗN1:+YX¯o{۞|I &32~8a #'I\籢>|'/'o2oHo$J881I $H_$}wҞc53gΒ%Kkkk:4UN䎝LwE 0#a$_W'o#sh̽`: z |Ѥ$Ç5e 0, IhiQtKװ-1Q I7i^p!''IMM+-23t 4BmA Kh0'j1pCPPcc#;v*, tuu1&8\adx(dxaͣgyPeT"ƢP;6cOBDZ]][ڵJs29APa˖-rӎTZ-X xI'`^}}=zu7MCǬ]*lZZZf3&n3`~l! Rb)uC $ȯK >9)ĉiii (4/*; MC]QRgW}H!͛7b%7@ʯhbq:?,C8ydZcL$F/q.h0eocW237O~ϡ!;wdy4%a(t=zt bUx[K*.|Q 鎝E{2f͚@]hmm52\__/3#^>B9:T'zᓒ`uyj&%#1#2Ό<63'>/ٝwO 貍zgCg ꎎ044 $oT >uLF`NgNLŤ~z&/w{.%2ܣޘv Dlw!ΦM& ef6g^Y׭[ i )he#aH>.\A&XGIP L.h4bFTQD2A&v񵹹1*O ]AAkA( S<qvz'2&(a4 (AܑцNIDž&Q̪U(YYYZ!N׬Yg>sY̓{A11C1Ct酎JJJ̎Ṣ٤8^HKp#%y+І:;;&u@ <B7mpMc|3ҥK= MG=)hO| kh+}$H AFG }Sg3{zzLB ˴"F93-T$ i5]y)T0I7oڴ?Ժ)FfF FSc@HEG͘i9U2,S]WW'q{z@tE67cJۙ.c&eiO8*?@W|<\#n"JY}k.4iEj' x ;A@anfC V]]͈k;݀7rQO^gOQbOr$6h9YLŋp-!мb "@v)a?J8o[1СCW޽{7hJ---Ȑ]y̸dmChw8!tq+8q- !y߰aQ+)8FfΟ?5(4;-,T^ڴio\ $$=`P0 ? [x]!.Yw9pu=_Z3v lx6@;!XjkΜY})JbP-u0]a*Ƽγ>?XYaĒ%+&e65Ybю6P8tvQfB?#o߾bi0yOfBXtr^V}-)))l`#64OdFoYzõH=#ϰ~<S64]RxX)T\FީJ/_PyFßh61KCNC\Cq-o%%%h kH-[f&]|%TIǏ1D;w䉠gb$ l|N>׆r1@tٽr1q]yu]]bej$H AH " żg&5n1zb m *y0w|eetqmll4&34z PF@ aI Nt.''w۶moy[ X Ж{%Su3IbTD=ֈ娅%#a< [UghƂWX&ЁMC9U6"%l9eqƚa(1 n15 c*-2DTĢd D8p`͚54 `Z^xh1t#G(t7)28[ ?++˰9PD233ovZF~y =~sa) ;ͯG_;޽{i5/C~~>@81tFLŸޔ+t Q2q7q_kh$H * ~L^S-{?scѸLfb7oIv֭ )<TSE Ç3wʔ)h0bњ)Z[[M\XX'0s~Y[[-2k#K_T&F(-ǘvGoDvMɃv4DPKzAJp z/UTTX ¥XܪȰVX J& XRP_bR#kg}c*W^Mݻw=k]-( MA5V 6x5R`qVans𥦦@ _@544̣ xs ɟ踿7׬YxR'+/-X@ 4B]vǪ gϞX>).[ `e_.Fl|"TZp |x^ʕ+?kCj:)Qڵk`h@rUUoN|cxǎ;R$Ex|c ިõQ0Ӥ(K A )$:禥{Y\&V]jɒ%LUjjwܡ{#e t V&PƜ 70L(dZ'PQ{\_i?1H)&at>2;v |)iӦA8 Y 86EHHe葀$QKevvvE=h\s3a4B]FLC5c#G@1.@Se6J* !6EFX2 uiHv'OqtsxRn tV,((` (ҋYwLe jݩ>w)kNGSRNO;y cضm>3P uߔc?(z饗4twäILʳb<m}JJ/p{{;V27h58H AJ#Xy=p 1={ Y蛩ZJդ!`/N>6z/'']X2&4oK6Y}}=`W 5رcty\8y$oE`O|G!M%%%Dww7YnȏӦm]~ݮ.N.T42ة!1s4aUVR5yׯOOO!a @;)xQw *<&̢mH;88b>vlZ7o$mDz~ܹЇ3fsn2C/f5sbFc=pSpss3skNN`c3( ǘݚD (wbmj*O v(-[@_|0IETUs p $hDT-80ޏ~# Iҁ F;|pFFpbjA/h =XeHYS q8 `f^>ϟ?ŗ^z 0&t>o_p~;{\'bDEW#)j*G$ uWj =֨~HLk: (`A8:VSkSWWצMꌈϜ9GQb5557fj taO !1 (z %6l̯Fi.3ڞf ١ߐ/@} /u0رc<\="h}TPP@zmaY;jo)C#̣17` $H nI4~co4Q83L|2T1e+,l0eʔ%K444PlH>|M}[˗MHB5q)4nj$?ajvv6,Ǔe@ aǃ/^}s? 9uZHKKw!R ee%'?jGy6:ysP80Dfu۷ǔNɑMCl&1ر2\]uot3ͳG\ A]DÿI(]Pbtg);k#8L P9`wqAev6w.a:`zں˪^Ɯ. K.Ջ)<%yҴ s1U` 4 DTX˸+p 4  6HD'@5&bc`b&aF$66`CnQ 8%]4 =2SᥛB RRRRUU0 PlnnzAAȇ <Gc9@8xqiRmh]zi"33 U цN=N:B»wG~;sŢӒυ:CEic[Sy tz~_oh; $H Ӓhc ]voL̪:SL>`tL̹z}^ydL̿a,`cwE]ƒU'x h7=v .]JI{W+7Li|qXsLM|q~uʊE)nV7f2?p哒qda9b={V^ }4 C^yy9A+ձAA>ʣ- 6`$w fgg3b t黰Qkao:H|;w؁@('(Ƽ$ :Nu1 3ɒ%p߿k:CLG@=Nmnע1tӿ5(lٲÇl~ڛn*10w-ZBC@!QnoPU5 $HG O p Bs sLQ!A#!`nᚹ,0a{yP&=f|zϞ=k7.݂h{wu@` ~q<[,K?^d8*E-3nݺ}vz!NTd DB# S޵kת̹pAD4Ģof6ݰ),PNF2 1sw&u71 pz," DKŸ LHIlc|kON ny+Pe*bϝIK)XhCӴKК<2,:u-QH f"koMwT<a6|߇5tVxy7܀V__ ?t=S]_+惣daa!͹z0B0_C{|~eއ%H A{Ŀg zk7 B @r p >a@QTpӐi-(6P6q_  X*5kVMM 0g*p<f+! %p%. wX G`Ft̬0a.% dNR/]jQ'N0 wڒQsrr VDZF- >L)^I0 bxhjϑ;\GOFg1lܹ--- /@EyFhÓw.y!jӯ` T}rR "I,? A _, yX@.Lf|`5Gfdf_~yyyp|noo/!Pưx`!tLW^50eb AXo4%]vrחNoe#DIǢв"Jfc>i?kb HOO'̦ hl:~Z.C 6l߾}.2J bN|4_>\cx@\D^ox2zc9spgٗ.]dx>=V+Ai 3t .Տ7ԩgn៖|T)**:zAx ^AF l݋{}YLE#%A $ȿ^~TT@n*Lzꇛ7&qP?~~#;UAXQVq+Pĭ@*'4toJPd&A_f,t= B2o&%%agOOĈ/B|>01.ZS#!0ϟLJ(| _a*6`$SFZEte<,ɔ)Sk^jwTy>sfq $H I@fzIs5038M}i!%K0}fs hK^ѣG=o:@ڠ5$!)8=A*LWfYp!ifbUYY_@ݶ6̀c1h!Obة 5`5JIOO7F"7ϟadwvvi`!K6} ZLE#y4h683BӴB3iPZ0Ao>p_ ԑqnmm]z+e(`aWvupɓ'y@Mf'K;c$ǨRPgAkHx7c Â7󇇇GD A +Ŀ?馌 &}f̘1o F .\/}K6mg闑ghˌ*~|.dŻ", $H A~%/| z'N!YnQ$X vttqټv理Τ( L>Ӄv <1~{{{!?ȅqMy:$PإB: M4; qjJS(èBxBcрt;gϞ beLga9^F˴ ;$g.f/yӛ`Άbwpgڴi `tt;: S 3f͚E+vZO< p0a 46#zD["q }ѣ $H QIL)SuFX(7<< <ΔT`^ :؀>===6 lաU %qI)PĥKu%$܌E~|~#)..6C!nݺOӆ&>yd|)(y>O0bn}LJrG6`(?AsQk۶mh9sӧ. ]SNnw:??رc(<짊'')~(x H\u<-.\~0fFzZ*6515u tUȌE Y 7J/f۫4G?) $H A~%13eiQ.7{zz)#4 P vQ0t-++U OKvPuun'D544zЇ>D{LOo}=`CCCfK4"2gd\2ŋf3\0Пkg̘Ib͛H ^COa9 A_]]]hl 6.1I4 &A}q„ 5fSMatRB]_1J}}YYY4A)SpSQL!D'_',wPrW>lc9h3 cJKK|G {fΜ}n۷%^ĢTF;::X(6]9hՂ!BIoo|v;2[ʹ5z=M35Mf8qbaaaccɧK?ټ(T32inrutuK,7w駟 0g$H A$&1plkkh|(//% 7ιz@˗/ A.tZa.@999y{kpZa|rlO1=ׯÇ`Ez u ;v >䧳gRrzCtttHSb vuuy^èـFݻ~ ӧ .JKK \Qj5yٌ;-X3 IZx|-))馛8`k-kSҺ_vڅԅB(#gB- GgSRR3g 'C庾)>?OǏ777;###7n0R~}0a8z͘;~iV\ QAཋ/w7:9&pm~ `#^ {epy|pR2(c$g]E ѢK.c\APϔ BuQ,??ކ 2Ch{{G\oFNnjҨtL䦛nrDiUUU0*j5F<@(4a׾g2"d BT6;0Ꞟ8`xɓO$H A$ao~pep `@5Xv…܇4Xba`΂a<3k,Sgff򙕕u 7Qlb聸iaنrΡ9 ԁʢŋCD`'a)SLp>)1*]XVPkTŔ !-o:ujםw$H AHr{.\с= <9 i2` nO (>1 .}B{|[ѡa<~E!i 0o|# ,X.HyUeσODa}iRBYk cZC,Bc~EХ3ƢMa0??cЌ͛7CkLSSUOIwaӧ3YRRXR Uf)yQ~$1(; ڍGF$H A+%h 'L<,%''CbŊӧOf999$;~x0P\jj*$gφ$WTTPH̦,7a`}ƾEybQ] @ޛ;w5'P_YsdܡNhʠ5ˌ{()pV " LJ;@ 0B(i:;G$H A[%?z9s:::3ϛA)pLrELwZ ̃͸|nn.4U\\ M4 f?}}}s06nr3ϼkyyy;~jkk*7=%Xgg'6P&.90 q/x4BíPرc<(ߢ07̋G¯ " Q@tQtfÁǎ + QBfftG\ʭ }KCh A $H_$2}2 [ 3gORRR@9̄U\rLA5Vt`'Xx1\sE3!"QU8~E3jcQXW"A.ztyL"\dee555Y&tФq푯ӧO#EÞ3gΘ:֮]~}xhs_Gil:BAG-IKKgϞ0a=$H AZ$ b>}Z \v (iիWgϞ 1ׅ;gw P_aHA>˖-koo nݺ{rb-e+AXtԭcŊNS c:88" :ߌ~嗱]WM 04@B]W[[klP { o|ZpT $H ,-X-ox9p`} :$c;CTlhh0f͚j~۶m!8`2 3 pʕׯ_?z((lF1?ylnnĉGFF_\\0ÇǢ/'O"%|c$&WXbɓ'}S@FSur=yf A $Q$ōϜ9/F 3ru &TKj^W_u -))\л|2-ZݭL1Uyy9-ܹsΜ9r)哓gϞ <u=p6h#&/|a` A $%RhŠԉ':::N< wXe8VׂJ^P\QQQkkTɓkASOrܡ$EEWZB4 TVALo4=``”ur}[$fd3x /^x$l $H AK"?o߾ &Q955^ۍEۣwERii)7$@;} L^}M6 ---\֯_V͚5 ~}̐K]Fr9syt 1 Tf'NhH@XZ P\`42!\'''S~ܹd,JUN4;4wܹF{A $H ;3g.^B5~xkLq .9q|2]tC(YTT;U;y:k"R4lZ3FHnWzhx===q@8Z QuAIm|$7--k # $H ADƿOI̙3}:ЌrU$ᚚ̥[RRVAJ!U\]~֦NzY fgg9kF`qE~8nx*x\.n^pܹso}*P$H AKߧǍE[@`$Ya$c#^jʔ) q;qD@}/st^<2ݢ5˗¤$h 4Slw_YY8M* ŋTয়~F̙:Bq---\WScƌ1ɖ-[ɡ)=A $HBIp1c bl(<̼X^^^ssK (^~݈ׅ f̘ qG Sp=}jJ^r$ (yx(SԩS.r}>c"gYfa^z饔WE=b7 uaΆTӿ A $o$8}&yډm:gݱ5/d5sɓ'yC@2At m`}D]wxb)¡!W3uԾִ46Cp=QE F{ $H +cl[@ULӮοAΜ9=&%%qlΆ A5zͤ6i$ʐyyy=ե_+ Mb7fqΜ94J[-*>= c!hb_gMoW!N9bc`'NLA8BFdɪMJiR%vtS5R BJ ! Nvm8Pʧb. g13scy|]w_0!B>;4[,4 x|nEXHqfU*x Vjp0LFP2}ҡG( ø%EroeYۍ- oX *a"cK.ia:v}bwMW !Bz[NʭX,OB ZRsja,Evŋjڠ|P?|0`A 6LFJbYކ9sx*DBa3330Ǐ0WrR`z`<"I!׿j48J &yirR)H4nUUL%abfR"yP;#M{ +v)Oƾϟ?`ͭ^|y}} Dtȡq9G!h\~&hL& g1<իW>)2;;k6!{rׯ_x>.Xa6M*V`B!|h\~!o*A`kǎp8 A~XK9Mȡ( {ĕR4;;199933lV^br,ni6!J2믄B!и 7ABеk~LfooO<n(Bq*1%>?ם;[[[F I_Պ[pB( N!dr rJ$AdX,Ig:#v\juxxj4OL!q޾h4F4e?ѣG=zdX:NFٳg4 z`T*ˉ m6Ϟ=àT*!^s17oH/`Hn?88a&qB!DԔWUX,Bpp=xk|F#;P(de4,zWD!K?9ROӍ0?~tߐ~DL&$B!wh_~_XH&8].t:rqUUE@"Io}B!Fbi6t:(hZ!JA]ZЗ[[~^B!M}ju\Rnw:X_ ݅. B!'MMMN8![>|+B!|zh_-.& T*|K!!h_!BGo{]`YU'  >' &D'L'()1>T'=/home/cspiel/projects/enblend/doc/seam-line-visualization.tifHHImageMagick 6.6.2-3 2010-06-07 Q16 http://www.imagemagick.orgenblend-enfuse-4.2/doc/lead-in.tex0000644000175000017500000000147612673203106014002 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \ifhevea\relax\else\shorttableofcontents{Short Contents}{0}\fi \tableofcontents \bigskip \begin{quotation} \noindent Chapters or sections marked with a ``\commonpart''-sign appear in both manuals, i.e.\ the \App{} manual and the \OtherApp{} manual. The commonality extends to \emph{all} sub-sections of the marked one. \end{quotation} \ifhevea \relax \else \listoftables \addcontentsline{toc}{section}{List of Tables} \listoffigures \addcontentsline{toc}{section}{List of Figures} \listof{exemplarbase}{List of Examples} \addcontentsline{toc}{section}{List of Examples} \cleardoublepage{} \fi \input{common-notation} \cleardoublepage{} \pagenumbering{arabic} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enfuse-applications.tex0000644000175000017500000007325712676175561016470 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Applications of \App]{\label{sec:applications}% \genidx[\rangebeginlocation]{applications of \App}% Applications of \App} This section describes some of the novel possibilities that \App{} offers the photographer. In contrast to the previous chapters, it centers around the effects on the final image. \section[What Makes Images Fusable?]{\label{sec:what-makes-images-fusable}% \genidx{images!fusable}% What Makes Images Fusable?} \begin{sloppypar} Images should align well to be suitable for fusion. However, there is no hard mathematical rule what ``well'' means. The alignment requirements for 16~MPixel images to yield a sharp $4" \times 6"$ print at 300\dmn{dpi} or even for web presentation are relatively low, whereas the alignment of 8~MPixel images for a $12" \times 18"$ print ought to be tight. \end{sloppypar} If the input images need to be aligned, \application{Hugin}\appidx{Hugin} (see also Appendix~\fullref{app:hugin}) is the tool of choice. It produces images exactly in the format that \App{} expects. Sometimes images naturally align extremely well so that no re-alignment is required. An image series with preprogrammed exposure steps taken in rapid succession where the camera is mounted on a heavy tripod and a humongous ball head, mirror lockup, and a cable release are used, comes to mind. When in doubt about what will work, try it, and judge for yourself. \noindent Useful ideas for a good alignment: \begin{itemize} \item Fix all camera parameters that are not explicitly varied. \begin{description} \item[Aperture:] Engage full manual or aperture-priority mode. \item[Auto-focus:] Disable ``Auto Focus''. Be aware that the auto-focus function could be linked to shutter-release button position ``half pressed'' or to the shutter release in insidious ways. \item[Closed eyepiece:] Close the eyepiece when using a cable release to suppress variations in stray light. (This tip applies only to single lens reflex cameras.) \item[Exposure time/Shutter speed:] Use the shortest possible exposure time or, in other words, use the fastest shutter speed to avoid blur caused by camera shake or motion blur. \item[Flash power:] Explicitly control the flash power of \emph{all} flashes. This is sometimes called ``flash exposure lock''. \item[Sensitivity:] Disable ``Auto \acronym{ISO}''. \item[White balance:] Disable ``Auto White Balance''. Instead, use the most suitable fixed white balance or take the white balance off a white card. When in doubt, use the setting ``Daylight'' or equivalent. \end{description} \item Steady the camera by any means. \begin{itemize} \item Apply your best camera bracing technique combined with controlled breathing. \item Prefer a monopod, or better, a rigid tripod with a heavy head. \item Use a cable release if possible. \item (This applies to cameras with a moving mirror only.) Engage ``mirror lockup''. \item Consider automatic bracketing when applicable. \item Activate camera- or lens-based image stabilization if you are sure that it improves the image quality in your particular case; otherwise disengage the feature. For some lens-based image stabilization systems, it is known that they ``lock'' into different positions every time they are activated. Moreover, some stabilization systems decrease the image quality if the lens is mounted on a tripod. \end{itemize} \item Fire in rapid succession. \end{itemize} %% http://www.usa.canon.com/dlc/controller?act=GetArticleAct&articleID=1786 \section[Repetition -- Noise Reduction]{\label{sec:repetition}% \genidx{series!simple}% \gensee{simple series}{series, simple}% \genidx{noise reduction}% Repetition -- Noise Reduction} \mainpurpose{Reduce noise} With the default settings, \App{} computes a weighted average of the input pixels. For a series of images, repeated with identical settings, this results in a reduction of (photon shot) noise. In other words, the dynamic range increases slightly, because the higher signal-to-noise ratio makes darker shades usable. Furthermore, smooth or glossy surfaces get a ``cleaner'' look, and edges become visually sharper. The nitty-gritty reportage look that sometimes stems from a high sensitivity setting disappears. Averaged images, and therefore low-noise images, are the base for a multitude of techniques like, for example, differences. The most prominent method in this class is dark-frame subtraction. \App{} sets defaults for the exposure-weight to \val{val:default-weight-exposure}, for saturation-weight to \val{val:default-weight-saturation} and for all other weights to zero, a good combination for noise reduction. Eliminating the saturation component with \option{--saturation\hyp weight=0.0} sometimes can be worth the extra run. \section[Exposure Series -- Dynamic Range Increase]{\label{sec:exposure-series--dynamic-range-increase}% \genidx{series!exposure}% \gensee{exposure series}{series, exposure}% \genidx{dynamic range increase}% Exposure Series -- Dynamic Range Increase} \mainpurpose{Increase manageable dynamic range} An exposure series is a set of images taken with identical parameters except for the exposure time. Some cameras even provide special functions to automate recording exposure series. See the instruction manual of your model for details. Also check out the features that Magic Lantern offers to shoot \acronym{HDR}-series and to extend the dynamic range right in the camera. \App{}'s defaults for exposure weight, \val{val:default-weight-exposure} and saturation weight, \val{val:default-weight-saturation} are well suited for fusion of \emph{color} images. Remember that saturation weighting only works for \acronym{RGB} data. Option~\option{--saturation-weight} helps to control burnt-out highlights, as these are heavily desaturated. Alternatively, use option~\option{--exposure-cutoff} to suppress noise or blown-out highlights without altering the overall brightness too much. If no image suffers from troublesome highlights, the relative saturation weight can be reduced and even be set to zero. For black and white images \sample{--entropy-weight} can be an alternative to \sample{--saturation-weight} because it suppresses overexposed pixels, as these contain little information. However, entropy weighting is not limited to gray-scale data; it has been successfully applied to \acronym{RGB} images, too. Note that entropy weighting considers \emph{each} color channel of an \acronym{RGB} image separately and chooses the channel with the minimum entropy as representative for the whole pixel. \App{} offers the photographer tremendous flexibility in fusing differently exposed images. Whether you combine only two pictures or a series of 21, \App{} imposes no limits on you. Accordingly, the photographic effects achieved range from subtle to surreal, like the late~1980s ``Max Headroom'' \acronym{TV}-Series, to really unreal. Like some time ago in the chemical days of photography, when a new developer opened unseen possibilities for artists, exposure fusion extends a photographer's expressive space in the digital age. Whether the results look good or bad, whether the images are dull or exciting, is entirely up the artist. In the next sections we give assistance to starters, and rectify several misconceptions about \App{}. \subsection[Tips For Beginners]{\label{sec:tips-for-beginners}% \genidx{exposure series!tips for beginners}% Tips For Beginners} Here are some tips to get you in business quickly. \begin{description} \item[Include the best single exposure.]\itemend Include the exposure you would have taken if you did not use \App{} in your series. It gives you a solid starting point. Think of the other images as augmenting this best single exposure to bring out the light and dark features you would like to see. \item[Begin with as small a number of images as possible.]\itemend Pre-visualizing the results of \App{} is difficult. The more images put into the fusion process and the wider their \acronym{EV}-spacing is, the more challenging visualizing the output image becomes. Therefore, start off with as few images as possible. You can take a larger series of images and only use part of it. \item[Start with a moderate \acronym{EV}-spacing.]\itemend As has been pointed out in the previous item, a wide \acronym{EV}-spacing makes pre-visualization harder. So start out with a spacing of $\slfrac{2}{3}$\dmn{EV} to $\slfrac{4}{3}$\dmn{EV}. \item[Use Magic Lantern's dual-\acronym{ISO} mode (and avoid \App).]\itemend Magic Lantern can reprogram a camera to take a \emph{single} short with \emph{two different} sensor speeds. They call it ``dual-\acronym{ISO}'' mode. The non-standard RAW~image created that way must be processed with \command{cr2hdr}\footnote{\command{cr2hdr} is part of Magic Lantern's source distribution.}, which produces a \acronym{DNG}~file readable with the usual RAW~converters. \end{description} \subsection[Common Misconceptions]{\label{sec:common-misconceptions}% \genidx{exposure series!common misconceptions}% Common Misconceptions} Here are some surprisingly common misconceptions about exposure series. \begin{description} \genidx{digital blending}% \genidx{blending exposures}% \item[A single image cannot be the source of an exposure series.]\itemend Raw-files in particular lend themselves to be converted multiple times and the results being fused together. The technique is simpler, faster, and usually even looks better than \uref{\luminouslandscapedigitalblending}{digital blending} (as opposed to using a graduated neutral density filter) or \uref{\gimpguruorgblendingexposures}{blending exposures} in an image manipulation program. Moreover, perfect alignment comes free of charge! \item[An exposure series must feature symmetrically-spaced exposures.]\itemend Twice wrong! Neither do the exposures have to be ``symmetric'' like \{0\dmn{EV}, $-\slfrac{2}{3}$\dmn{EV}, $+\slfrac{2}{3}$\dmn{EV}\}, nor does the number of exposures have to be odd. Series like \{$-\slfrac{4}{3}$\dmn{EV}, $-\slfrac{1}{3}$\dmn{EV}, $+\slfrac{1}{3}$\dmn{EV}\} or \{$-1$\dmn{EV}, 1\dmn{EV}\} might be just right. By the way, the order in which the images were taken does not matter either. \genidx{light probe}% \item[An exposure series must cover the whole dynamic range of the scene.]\itemend If you do not want to cover the whole range, you do not have to. Some \acronym{HDR} programs require the user to take a light probe, whereas \App{} offers the user complete freedom of exposure. \begin{geeknote} \uref{\debevecorg}{Paul E.~Debevec} defines: ``A light probe image is an omnidirectional, high dynamic range image that records the incident illumination conditions at a particular point in space.'' \end{geeknote} \item[All exposure values must be different.]\itemend You can repeat any exposure as often as you like. That way you combine an exposure series with parts of \sectionName~\ref{sec:repetition}, emphasizing the multiply occurring exposures and reducing noise. \end{description} \section[Flash Exposure Series -- Directed Lighting]{% \label{sec:flash-exposure-series--directedlighting}% \genidx{series!flash exposure}% \gensee{flash exposure series}{series, flash exposure}% \genidx{dynamic range increase}% Flash Exposure Series -- Directed Lighting} \mainpurpose{???} \fixme{Text?} \section[Polarization Series -- Saturation Enhancement]{% \label{sec:polarization-series--saturation-enhancement}% \genidx{series!polarization}% \gensee{polarization series}{series, polarization}% \genidx{saturation enhancement}% Polarization Series -- Saturation Enhancement} \mainpurpose{Reflection suppression, saturation enhancement} In the current implementation of \App{}, it is not possible in general to fuse a polarization series. Na\"ively (ab)using \sample{--saturation-weight} will not work. \section[Focus Stacks -- Depth-of-Field Increase]{% \label{sec:focus-stacks--depth-of-field-increase}% \genidx{focus stacks}% \genidx{depth-of-focus increase}% Focus Stacks -- Depth-of-Field Increase} \mainpurpose{Synthetic Depth-of-Field Increase} \genidx{depth-of-field}% \gensee{DoF@\acronym{DoF}}{depth-of-field}% A focus stack is a series of images where the distance of the focal plane from the sensor varies. Sloppily speaking, the images were focused at different distances. Fusing such a stack increases the depth-of-field (\acronym{DoF}) beyond the physical limits of diffraction. \subsection[Why create focus stacks?]{\label{sec:why-create-focus-stacks}% \genidx{focus stacks!why to create them?}% Why create focus stacks?} Given \begin{itemize} \item a fixed sensor or film size, \item a lens' particular focal length, and \genidx{circle-of-confusion}% \gensee{CoC@\acronym{CoC}}{circle-of-confusion}% \item a notion about ``sharpness'', technically speaking the size of the circle-of-confusion (\acronym{CoC}) \end{itemize} \genidx{depth-of-field}% \noindent the photographer controls the depth-of-field with the aperture. Smaller apertures -- this is larger aperture numbers -- increase the \acronym{DoF} and vice versa. However, smaller apertures increase diffraction which in turn renders the image unsharp. So, there is an optimum aperture where the photographer gets maximum \acronym{DoF}. Sadly, for some purposes like macro shots it is not enough. One way out is to combine the sharp parts of images focused at different distances, thereby artificially increasing the total \acronym{DoF}. This is exactly what \App{} can do. \genidx{aperture!sweet spot}% \gensee{sweet spot aperture}{aperture, sweet spot}% All lenses have a so called ``sweet spot'' aperture, where their resolution is best. Taking pictures at this aperture, the photographer squeezes the maximum quality out of the lens. But: the ``sweet spot'' aperture often is only one or two stops away from wide open. Wouldn't it be great to be able combine these best-possible images to form one high-quality, sufficient-\acronym{DoF} image? Welcome to \App{}'s local-contrast selection abilities. \subsection[Preparing Focus Stacks]{\label{sec:preparing-focus-stacks}% \genidx{focus stacks!preparation}% Preparing Focus Stacks} We are going to combine images with limited \acronym{DoF} to increase their in-focus parts. The whole process is about image sharpness. Therefore, the input images must align very well, not just well, but very well. For optimum results the maximum control point distance in \application{Hugin} should not exceed 0.3--0.5~pixels to ensure perfect blending. \genidx{signal-to-noise ratio}% \gensee{SNR@\acronym{SNR}}{signal-to-noise ratio}% As in all image fusion operations it is preferable to use 16~bit linear (i.e. gamma = 1) images throughout, but 8~bit gamma-encoded images will do. Naturally, high signal-to-noise (\acronym{SNR}) ratio input data always is welcome. \subsection[Local Contrast Based Fusing]{\label{sec:local-contrast-based-fusing}% \genidx{local-contrast-based fusing}% \genidx{fusing!local-contrast-based}% \genidx{focus stacks!fusing}% Local Contrast Based Fusing} A bare bones call to \App{} for focus stacking could look like this. \begin{terminal} \$ enfuse \bslash \\ ~~~~--exposure-weight=0 \bslash \\ ~~~~--saturation-weight=0 \bslash \\ ~~~~--contrast-weight=1 \bslash \\ ~~~~--hard-mask \bslash \\ ~~~~\dots{} \bslash \\ ~~~~--output=output.tif \bslash \\ ~~~~input-<0000-9999>.tif \end{terminal} Here is what each option causes: \begin{codelist} \item[--exposure-weight=0]\itemend Switch \strong{off} exposure based pixel selection. The default weight is \val{val:default-weight-exposure}. \item[--saturation-weight=0]\itemend Switch \strong{off} saturation based pixel selection. The default weight is \val{val:default-weight-saturation}. \item[--contrast-weight=1]\itemend Switch \strong{on} pixel selection based on local contrast. \item[--hard-mask]\itemend Select the best pixel from the image stack and ignore all others. Without this option, \App{} uses all pixels in the stack and weights them according to their respective quality, which in our case is local contrast. Without \sample{--hard-mask}, the result will always look a bit soft. See also \sectionName~\fullref{sec:local-contrast-weighting}. \end{codelist} If you want to see some entertaining progress messages -- local-contrast weighting takes a while --, also pass the \option{--verbose}~option for an entertaining progress report. \subsection[Basic Focus Stacking]{\label{sec:basic-focus-stacking}% \genidx{focus stacking!basic}% \gensee{basic focus stacking}{focus stacking, basic}% Basic Focus Stacking} For a large class of image stacks \App{}'s default algorithm, as selected in \ref{sec:local-contrast-based-fusing}, to determine the sharpness produces nice results. The algorithm uses a moving square window, the so-called contrast window. It computes the standard deviation of the pixels inside of the window. The program then selects the window's center pixel of the image in the stack where the standard deviation is largest, that is, the local contrast reaches the maximum. However, the algorithm fails to deliver good masks for images which exhibit high contrast edges on the scale of the contrast window size. The typical artifacts that show up are \begin{itemize} \item faint dark seams on the light side of the high contrast edges and \item extremely soft, slightly lighter seams on the dark side of the high contrast edges, \end{itemize} \noindent where the distance of the seams from the middle of the edge is comparable to the contrast window size. If your results do not show any of these artifacts, stick with the basic algorithm. Advanced focus stacking, as described in the next sections, delivers superior results in case of artifacts, though requires manually tuning several parameters. \subsection[Advanced Focus Stacking]{\label{sec:advanced-focus-stacking}% \genidx{focus stacking!advanced}% \gensee{advanced focus stacking}{focus stacking, advanced}% Advanced Focus Stacking} If your fused image shows any of the defects described in the previous section, you can try a more difficult-to-use algorithm that effectively works around the seam artifacts. It is described in the next section. \subsubsection[Detailed Look at the Problem]{\label{sec:detailed-look-at-the-problem}% \genidx{local contrast problem}% Detailed Look at the Problem} Let us use an example to illustrate the problem of relating the sharpness with the local contrast variations. Say we use a $5 \times 5$ contrast window. Moreover, let \code{sharp\_edge} and \code{smooth\_edge} be two specific configurations: \begin{literal} sharp\_edge~=~~[~~~~0, ~~0, 200, ~~0, ~~0; \\ ~~~~~~~~~~~~~~~~~~~0, 225, ~~0, ~~0, ~~0; \\ ~~~~~~~~~~~~~~~~~~~0, 255, ~~0, ~~0, ~~0; \\ ~~~~~~~~~~~~~~~~~215, ~~0, ~~0, ~~0, ~~0; \\ ~~~~~~~~~~~~~~~~~200, ~~0, ~~0, ~~0, ~~0] \end{literal} \begin{literal} smooth\_edge~=~[~~~~0, ~62, 125, 187, 250; \\ ~~~~~~~~~~~~~~~~~~~1, ~63, 126, 188, 251; \\ ~~~~~~~~~~~~~~~~~~~2, ~65, 127, 190, 252; \\ ~~~~~~~~~~~~~~~~~~~3, ~66, 128, 191, 253; \\ ~~~~~~~~~~~~~~~~~~~5, ~67, 130, 192, 255] \end{literal} \noindent where \sample{;} separates the rows and \sample{,} separates the columns. This is in fact \uref{\gnuorgoctave}{Octave} syntax. \figureName~\ref{fig:sharp-edge} and~\ref{fig:smooth-edge} show plots of the matrices \code{sharp\_edge} and~\code{smooth\_edge}. \begin{figure} \begin{maxipage} \centering \includeimage{sharp-edge} \end{maxipage} \caption[Sharp edge]{\label{fig:sharp-edge}% 3D-plot augmented by contour plot of the matrix~\code{sharp\_edge}.} \end{figure} \begin{figure} \begin{maxipage} \centering \includeimage{smooth-edge} \end{maxipage} \caption[Smooth edge]{\label{fig:smooth-edge}% 3D-plot augmented by contour plot of the matrix~\code{smooth\_edge}.} \end{figure} Our intuition lets us ``see'' an extremely sharp edge in the first matrix, whereas the second one describes an extraordinarily smooth diagonal intensity ramp. Which one will be selected? Well, \code{sharp\_edge} has a standard deviation of 88.07 and \code{smooth\_edge} has 88.41. Thus, \code{smooth\_edge} wins, contradicting our intuition, and even worse, our intention! Sadly, configurations like \code{smooth\_edge} occur more often with high-quality, good \uref{\luminouslandscapebokeh}{bokeh} lenses. In fact, they are the very manifestation of ``good bokeh''. Therefore, Laplacian edge detection plays an important role when working with high-quality lenses. \subsubsection[\propername{Laplacian} Edge Detection]{\label{sec:laplacian-edge-detection}% \genidx{edge detection!Laplacian@\propername{Laplacian}}% \gensee{Laplacian edge detection@\propername{Laplacian} edge detection}% {edge detection, \propername{Laplacian}}% \propername{Laplacian} Edge Detection} \App{} provides a Laplacian-based algorithm that can help in situations where weighting based on the standard deviation fails. It is activated with a positive value for \metavar{SCALE} in \option{--contrast-edge-scale}=\metavar{SCALE}. The Laplacian will detect two-dimensional \emph{curvature} on the scale of \metavar{SCALE}. Here and in the following we simply speak of ``curvature'' where we mean ``magnitude of curvature''. That is, we shall not distinguish between convex and concave edges. \App{} always use the magnitude of curvature for weighting. Typically, \metavar{SCALE} ranges between 0.1~pixels and 0.5~pixels, where 0.3~pixels are a reasonable starting point. To find the best value for \metavar{SCALE} though, usually some experimentation will be necessary. Use \sample{--save-masks} to get all soft-mask (default: \mbox{\code{\val{val:default-soft-mask-template}}}) and hard-mask files (default: \mbox{\code{\val{val:default-hard-mask-template}}}). Check how different scales affect the artifacts. Also see Chapter~\fullref{sec:understanding-masks}. \subsubsection[Local Contrast Enhancement]{\label{sec:local-contrast-enhancement}% \genidx{contrast enhancement!local}% \gensee{local contrast enhancement}{contrast enhancement, local}% Local Contrast Enhancement} Sometimes \App{} misses smoother edges with \sample{--contrast-edge-scale} and a little local contrast enhancement (\acronym{LCE}) helps. Set \option{--contrast\hyp edge\hyp scale}=\feasiblebreak \metavar{SCALE}:\feasiblebreak \metavar{LCE\hyp SCALE}:\feasiblebreak \metavar{LCE\hyp FACTOR}, where \metavar{LCE\hyp SCALE} and \metavar{LCE\hyp FACTOR} work like the \uref{\cambridgeincolourcomunsharpmask}{unsharp mask} filters in various image manipulation programs. Start with \metavar{LCE\hyp SCALE} ten times the value of \metavar{SCALE} and a \metavar{LCE\hyp FACTOR} of 2--5. \metavar{LCE\hyp SCALE} can be specified as a percentage of \metavar{SCALE}. \metavar{LCE\hyp FACTOR} also can be specified as a percentage. Examples: \begin{literal} --contrast-edge-scale=0.3:3.0:3 \\ --contrast-edge-scale=0.3:1000\%:3.0 \\ --contrast-edge-scale=0.3:3:300\% \\ --contrast-edge-scale=0.3:1000\%:300\% \end{literal} By default \acronym{LCE} is turned off. \subsubsection[Suppressing Noise or Recognizing Faint Edges]{% \label{sec:suppressing-noise-or-recognizing-faint-edges}% \genidx{advanced focus stacking!suppressing noise}% \genidx{advanced focus stacking!recognizing faint edges}% Suppressing Noise or Recognizing Faint Edges} The \propername{Laplacian}-based algorithm is much better at resisting the seam problem than the local-contrast algorithm, but it has two shortcomings: \begin{compactenumerate} \item The \propername{Laplacian} is very susceptible to noise and \item it fails to recognize faint edges. \end{compactenumerate} \noindent The option~\option{--contrast-min-curvature} option helps to mitigate both flaws. The argument to \option{--contrast-min-curvature}=\metavar{CURVATURE} either is an absolute lightness value, e.g.\ 0\dots255 for 8~bit data and 0\dots65535 for 16~bit data, or, when given with a \sample{\%}-sign it is a relative lightness value ranging from 0\% to~100\%. To suppress unreal edges or counter excessive noise, use the \option{--contrast\hyp min\hyp curvature}~option with a \emph{negative} curvature measure~\metavar{CURVATURE}. This forces all curvatures less than $-\metavar{CURVATURE}$ to zero. A \emph{positive} curvature measure~\metavar{CURVATURE} makes \App{} merge the \acronym{LoG} data with the local-contrast data. Every curvature larger than or equal to \metavar{CURVATURE} is left unchanged, and every curvature less than \metavar{CURVATURE} gets replaced with the rescaled local-contrast data, such that the largest local contrast is just below \metavar{CURVATURE}. This combines the best parts of both techniques and ensures a precise edge detection over the whole range of edge curvatures. \noindent\strong{Summary} \begin{codelist} \item[\option{--contrast-edge-scale=0.3}]\itemend Use \acronym{LoG} to detect edges on a scale of 0.3~pixels. Apply the default grayscale projector: \code{average}. \item[\itempar{\option{--contrast-edge-scale=0.3} \option{--gray-projector=l-star}}]\itemend Use \acronym{LoG} to detect edges on a scale of 0.3~pixels. Apply the L*-grayscale projector. \item[\option{--contrast-edge-scale=0.3:3:300\%}]\itemend Use \acronym{LoG} to detect edges on a scale of 0.3~pixels, pre-sharpen the input images by 300\% on a scale of 3~pixels. Apply the default grayscale projector: \code{average}. \item[\itempar{\option{--contrast-edge-scale=0.3} \mbox{\option{--contrast-min-curvature=-0.5\%}}}]\itemend Use \acronym{LoG} to detect edges on a scale of 0.3~pixels. Apply the default grayscale projector: \code{average} and throw away all edges with a curvature of less than 0.5\%. \item[\itempar{\mbox{\option{--contrast-edge-scale=0.3}} \mbox{\option{--contrast-min-curvature=0.5\%}} \mbox{\option{--contrast-window-size=7}}}]\itemend Use \acronym{LoG} to detect edges on a scale of 0.3~pixels. Apply the default grayscale projector: \code{average} and throw away all edges with a curvature of less than 0.5\% and replace the \acronym{LoG} data between 0\% and 0.5\% with \acronym{SDev} data. Use a window of $7 \times 7$~pixel window to compute the \acronym{SDev}. \end{codelist} \subsubsection[Focus Stacking Decision Tree]{% \label{sec:focus-stacking-decision-tree}% \genidx{decision tree!focus stacking}% \gensee{focus stacking decision tree}{decision tree, focus stacking}% Focus Stacking Decision Tree} \figureName~\ref{fig:focus-stacking-decision-tree} helps the user to arrive at a well-fused focus stack with as few steps as possible. \begin{figure} \begin{maxipage} \centering \includeimage{focus-stack-decision-tree} \end{maxipage} \caption[Focus stacking decision tree.]{\label{fig:focus-stacking-decision-tree}% Focus stacking decision tree.} \end{figure} Always start with the default, contrast weighting with a local contrast window. Only if seams appear as described in \sectionName~\ref{sec:advanced-focus-stacking} switch to \propername{Laplacian}-of-\propername{Gaussian} contrast detection. If some seams remain even in \acronym{LoG}-mode, decrease the sensitivity of the edge detection with a positive \code{--contrast\hyp min\hyp curvature}. A too high value of \code{--contrast\hyp min\hyp curvature} suppresses fine detail though. Part of the detail can be brought back with pre-sharpening, that is, \ref{sec:local-contrast-enhancement} or combining \acronym{LoG} with local-contrast-window mode by using a negative \code{--contrast\hyp min\hyp curvature}. Carefully examining the masks (option~\option{--save-masks}) that \App{} uses helps to judge the effects of the parameters. \subsection[Tips For Focus Stacking Experts]{\label{sec:tips-for-focus-stacking-experts}% \genidx{tips!focus stacking experts}% \gensee{expert focus stacking tips}{tips, focus stacking experts}% Tips For Focus Stacking Experts} We have collected some advice with which even focus-stacking adepts can benefit. \begin{itemize} \genidx{sensor!use clean}% \item Ensure that the sensor is clean. Aligning focus stacks requires varying the viewing angle, which corresponds to a changing focal length. Hence, the same pixel on the sensor gets mapped onto different positions in the final image. Dirt spots will occur not only once but as many times as there are images in the stack -- something that is no fun to correct in post-processing. \genidx{dark frame}% \genidx{subtraction of dark frame}% \genidx{hot pixels}% \genidx{pixels!hot}% Along the same lines, the photographer may want to consider to prepare dark frames before, and possibly also after, the shoot of the focus stack, to subtract hot pixels before fusion. \item Prefer a low-sensitivity setting (``\acronym{ISO}'') on the camera to get low-noise images. Fusing with option~\option{--hard-mask}\optidx{--hard-mask} does not average, and thus does not suppress any noise in the input images. \item If the transition of in-focus to out-of-focus areas is too abrupt, record the images with closest and farthest focusing distances twice: first with the intended working aperture, and a second time with a small aperture (large aperture number). \genidx{natural sharp-unsharp transition}% \genidx{transition!natural sharp-unsharp}% The small aperture will give the fused image a more natural in-focus to out-of-focus transition and the working-aperture shots supply the detail in the in-focus regions. \item Consider the use of Magic Lantern (\appendixName~\fullref{app:magiclantern}) to automate the creation of focus stacks. \end{itemize} \genidx[\rangeendlocation]{applications of \App} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/internal-enblend-flow.dot0000644000175000017500000000573012562317012016641 00000000000000digraph InternalEnblendFlow { graph [uml_activity_graph, uml_compressed_layout] node [uml_activity] _start [uml_start] load_next_image [label = "Load next image"] if_load_masks_branch [uml_branch] if_coarse_mask_branch [uml_branch] scale_down_mask [label = "Scale down mask"] if_graphcut_branch [uml_branch] compute_nft [label = "Nearest-Feature Transform\n(NFT)"] compute_graphcut [label = "Graph Cut\n(GC)"] if_optimize_branch [uml_branch] run_optimizers [label = "Optimizer Chain..."] if_save_masks_branch [uml_branch] save_mask [label = "Write generated,\npossibly optimized mask"] if_save_mask_and_output_branch [uml_branch] load_mask [label = "Read matching,\nexternal mask"] if_load_masks_AND_optimize_merge [uml_merge] run_blender [label = "Blend using multi-resolution\nspline algorithm;\n--levels"] _finish [uml_finish] node [uml_note] load_next_image_note [label = "Image includes its mask"] initial_mask_note [label = "Initial mask"] final_mask_note [label = "Final mask"] {rank = same; load_next_image; load_next_image_note} {rank = same; compute_nft; compute_graphcut; initial_mask_note} {rank = same; if_load_masks_AND_optimize_merge; final_mask_note} edge [uml_edge] _start -> load_next_image load_next_image -> if_load_masks_branch if_load_masks_branch -> if_coarse_mask_branch [taillabel = " [default] ", weight = 10] if_coarse_mask_branch -> scale_down_mask [taillabel = " [default]\n--coarse-mask ", weight = 10] if_coarse_mask_branch -> if_graphcut_branch [taillabel = " --fine-mask "] scale_down_mask -> if_graphcut_branch [weight = 10] if_load_masks_branch -> load_mask [taillabel = " --load-masks "] load_mask -> if_load_masks_AND_optimize_merge if_graphcut_branch -> compute_nft [taillabel = " --primary-seam-generator=\nnearest-feature-transform "] compute_nft -> if_optimize_branch if_graphcut_branch -> compute_graphcut [taillabel = "[default]\n --primary-seam-generator= \ngraph-cut", weight = 10] compute_graphcut -> if_optimize_branch if_optimize_branch -> run_optimizers [taillabel = " [default]\n--optimize ", weight = 10] if_optimize_branch -> if_save_masks_branch [taillabel = " --no-optimize "] run_optimizers -> if_save_masks_branch [weight = 10] if_save_masks_branch -> if_load_masks_AND_optimize_merge [taillabel = " [default] ", weight = 10] if_save_masks_branch -> save_mask [taillabel = " --save-masks "] save_mask -> if_save_mask_and_output_branch if_save_mask_and_output_branch -> run_blender [taillabel = " --output "] if_save_mask_and_output_branch -> _finish if_load_masks_AND_optimize_merge -> run_blender run_blender -> _finish edge [uml_note_edge] load_next_image -> load_next_image_note #-- compute_nft -> initial_mask_note compute_graphcut -> initial_mask_note if_load_masks_AND_optimize_merge -> final_mask_note } enblend-enfuse-4.2/doc/exemplar.hva0000644000175000017500000000135612667245144014274 00000000000000%% -*- latex -*- %% This file is part of Enblend. %% Licence details can be found in the file COPYING. %% Additional floating environment `exemplar'. %% Modeled closely after Hevea's original code. \setenvclass{exemplar}{exemplar} \newcommand{\@exrule}{\begin{center}\@hr{.8\linewidth}{2pt}\end{center}} \newcounter{exemplar} \renewcommand{\theexemplar}{\thesection.\arabic{exemplar}} \newcommand{\exemplarname}{Exemplar} \newenvironment{exemplar}[1][]% {\@forcecommand{\caption}[2][]{\hva@caption{exemplar}{##2}}% \@open@quote{\envclass@attr{exemplar}}\@exrule}% {\@exrule\@close@quote} \newenvironment{exemplar*}[1][]% {\begin{exemplar}[#1]}% {\end{exemplar}} enblend-enfuse-4.2/doc/Makefile.am0000644000175000017500000004037412676175553014024 00000000000000SUBDIRS = examples .NOTPARALLEL: TEXINPUTS = .:$(LATEX2HTML_LIBDIR):$(srcdir): export TEXINPUTS LATEX_FLAGS = -file-line-error -halt-on-error -interaction nonstopmode ## Enabled pieces of information in a LaTeX *.log file in non-verbose mode. ## h outputs only warnings about horizontal boxes ## r displays warnings about references ## t displays all *.tex files used TEXLOGANALYSER_FLAGS = $(if $(subst cat,,$(TEXLOGANALYSER)),-hrt,) MAKEINDEX_FLAGS = $(if $(subst false,,$(AM_V_P)),,-q) ## Papersize for some converters, usually: ## a4 ## a5 ## b5 ## executive ## legal ## letter PAPERSIZE = a4 ## Resolution for some converters in dots-per-inch PRINT_RESOLUTION = 600 DVIPS_FLAGS = -q -t $(PAPERSIZE) -D$(PRINT_RESOLUTION) -Z ## Some other "interesting" flags for Hevea: ## -dv add borders to block-level elements ## -mathml enable MathML output LATEX2HTML_FLAGS = -O -I . -I $(srcdir) -fix ## Flags for Hacha, see also http://hevea.inria.fr/doc/cutname.html SPLITHTML_FLAGS = -tocbis GNUPLOT_FLAGS = --default-settings -e 'DATA_DIR="$(srcdir)"' ## Some possible plot sizes (in pixels) with identical aspect ratios: ## 648,480 ## 720,540 ## 800,600 GNUPLOT_PNG_TERMINAL_OPTIONS = enhanced transparent truecolor size 720,540 ## Some possible plot sizes (in inches) with identical aspect ratios: ## 4.0,3.0 ## 4.5,3.375 ## 5,3.75 GNUPLOT_EPSLATEX_TERMINAL_OPTIONS = color size 4.5in,3.375in DOTPP = $(M4) DOTPP_FLAGS = --fatal-warnings --prefix-builtins --synclines DOTPP_PRELOAD = $(srcdir)/uml-dot.m4 DOT_FLAGS = DOT_EPS_FLAGS = -Gsize=4.75,8.5 DOT_PNG_FLAGS = -Gbgcolor=transparent -Gresolution=$(PRINT_RESOLUTION) SVGCONVERT_FLAGS = --dpi-x=96 --dpi-y=96 SVGCONVERT_EPS_FLAGS = $(SVGCONVERT_FLAGS) --format=eps SVGCONVERT_PNG_FLAGS = $(SVGCONVERT_FLAGS) --format=png CLEANTEX = $(srcdir)/cleantex CONFIG2TEX = $(srcdir)/config2tex DOCSTRINGS = $(srcdir)/docstrings UPDATED_ON = $(srcdir)/updated-on UPDATED_ON_FLAGS = \ --database=source-code-manager \ --override='none:\datebyunknown' \ --override='fs:\datebyfs' \ --override='scm:\datebyscm' VPATH =# must be empty to keep srcdir free of products ######################################################################## .PHONY: all-local all-local: ps-local html-local .PHONY: ps-local ps-local: enblend.ps enfuse.ps .PHONY: pdf-local pdf-local: enblend.pdf enfuse.pdf .PHONY: html-local html-local: enblend.html enfuse.html .PHONY: dvi-local dvi-local: enblend.dvi enfuse.dvi .PHONY: enblend enblend: enblend.ps enblend.html .PHONY: enfuse enfuse: enfuse.ps enfuse.html .PHONY: clean-local clean-local: - rm -f *.eps *.png *.pstex *.gp - rm -f *.{g,o,p,a}nd *.{g,o,p,a}dx - rm -f *.idx *.ilg *.ind *.lo{a,f,t,x} *.toc - rm -f *.aux *.log *.dvi *.ps *.pdf - rm -f *.html *.haux *.hind *.hlog - rm -f en*.{htoc,hpnd,hond,hgnd,haux,hand,hdgx} - rm -f enblend.out enblend.image.{tex,out} enblend-{variables,version}.tex - rm -f enfuse.out enfuse.image.{tex,out} enfuse-{variables,version}.tex - rm -f *_motif.gif - rm -f enblend{-index.html,.css,[0-9][0-9][0-9].html} - rm -f enfuse{-index.html,.css,[0-9][0-9][0-9].html} .PHONY: distclean-local distclean-local: clean-local - rm -f config-h.tex dynamic-preamble.tex - rm -f *~ .PHONY: FORCE .PHONY: split-html split-html: split-enblend-html split-enfuse-html .PHONY: split-enblend-html split-enblend-html: enblend-index.html .PHONY: split-enfuse-html split-enfuse-html: enfuse-index.html ######################################################################## config2tex_verbose = $(config2tex_verbose_@AM_V@) config2tex_verbose_ = $(config2tex_verbose_@AM_DEFAULT_V@) config2tex_verbose_0 = @echo " CFG2TEX $@"; convert_verbose = $(convert_verbose_@AM_V@) convert_verbose_ = $(convert_verbose_@AM_DEFAULT_V@) convert_verbose_0 = @echo " CONVERT $@"; docstrings_verbose = $(docstrings_verbose_@AM_V@) docstrings_verbose_ = $(docstrings_verbose_@AM_DEFAULT_V@) docstrings_verbose_0 = @echo " DOCSTR $@"; dvips_verbose = $(dvips_verbose_@AM_V@) dvips_verbose_ = $(dvips_verbose_@AM_DEFAULT_V@) dvips_verbose_0 = @echo " DVIPS $@"; dot_verbose = $(dot_verbose_@AM_V@) dot_verbose_ = $(dot_verbose_@AM_DEFAULT_V@) dot_verbose_0 = @echo " DOT $@"; svgconvert_verbose = $(svgconvert_verbose_@AM_V@) svgconvert_verbose_ = $(svgconvert_verbose_@AM_DEFAULT_V@) svgconvert_verbose_0 = @echo " SVGCONV $@"; gnuplot_verbose = $(gnuplot_verbose_@AM_V@) gnuplot_verbose_ = $(gnuplot_verbose_@AM_DEFAULT_V@) gnuplot_verbose_0 = @echo " GNUPLOT $@"; install_verbose = $(install_verbose_@AM_V@) install_verbose_ = $(install_verbose_@AM_DEFAULT_V@) install_verbose_0 = @echo " INSTALL $@"; latex_verbose = $(call latex_verbose_@AM_V@,$(1)) latex_verbose_ = $(call latex_verbose_@AM_DEFAULT_V@,$(1)) latex_verbose_0 = @echo " LATEX [pass $(1)] $@"; makeindex_verbose = $(call makeindex_verbose_@AM_V@,$(1)) makeindex_verbose_ = $(call makeindex_verbose_@AM_DEFAULT_V@,$(1)) makeindex_verbose_0 = @echo " MKIDX [$(1)] $@"; ######################################################################## ## Alternative PDF generation: LaTeX -> DVI -> PostScript -> PDF PS2PDF_FLAGS = -r$(PRINT_RESOLUTION) %.ps.pdf: %.ps $(AM_V_GEN)$(PS2PDF) $(PS2PDF_FLAGS) $< $@ ## Alternative PDF generation: LaTeX -> DVI -> PDF DVIPDF_FLAGS = -p $(PAPERSIZE) -r $(PRINT_RESOLUTION) -v %.dvi.pdf: %.dvi $(AM_V_GEN)$(DVIPDF) $(DVIPDF_FLAGS) -o $@ $< %.ps: %.dvi $(dvips_verbose)$(DVIPS) $(DVIPS_FLAGS) -o $@ $< SHOW_LATEX_LOG = \ rc=$$?; \ if $(AM_V_P) || test $$rc -ne 0; \ then \ cat $(1); \ else \ $(TEXLOGANALYSER) $(TEXLOGANALYSER_FLAGS) $(1); \ fi; \ test $$rc -eq 0 %.dvi %.pdf: $(srcdir)/%.tex $(srcdir)/endoc.ist @- rm -f $(foreach ext,aux toc lo[^g] ?nd ?dx,$(basename $@).$(ext)) $(call latex_verbose,1)$(LATEX_TRANSLATOR) $(LATEX_FLAGS) $(EXTRA_LATEX_FLAGS) $< >/dev/null; \ $(call SHOW_LATEX_LOG,$*.log) $(call makeindex_verbose,general terms)$(MAKEINDEX) $(MAKEINDEX_FLAGS) -s $(srcdir)/endoc.ist -o $*.gnd $*.gdx $(call makeindex_verbose,command-line options)$(MAKEINDEX) $(MAKEINDEX_FLAGS) -o $*.ond $*.odx $(call makeindex_verbose,applications and programs)$(MAKEINDEX) $(MAKEINDEX_FLAGS) -o $*.pnd $*.pdx $(call makeindex_verbose,syntactic comments)$(MAKEINDEX) $(MAKEINDEX_FLAGS) -o $*.and $*.adx $(call latex_verbose,2)$(LATEX_TRANSLATOR) $(LATEX_FLAGS) $(EXTRA_LATEX_FLAGS) $< >/dev/null; \ $(call SHOW_LATEX_LOG,$*.log) @ max_iter=5; \ iter=2; \ while [ $$iter -le $$max_iter ] && \ $(GREP) '^LaTeX Warning: There were undefined references' $*.log >/dev/null && \ $(GREP) '^LaTeX Warning: Label(s) may have changed' $*.log >/dev/null; \ do \ iter=$$((iter + 1)); \ if $(AM_V_P); then :; else printf ' LATEX [pass %d] %s\n' $$iter $@; fi; \ $(LATEX_TRANSLATOR) $(LATEX_FLAGS) $(EXTRA_LATEX_FLAGS) $< >/dev/null; \ $(call SHOW_LATEX_LOG,$*.log); \ done; \ if [ $$iter -le $$max_iter ]; \ then \ printf 'Fixpoint reached in %i step(s)\n' $$iter; \ else \ printf 'Fixpoint NOT reached after %i steps; still undefined or loose labels\n' $$iter; \ $(GREP) '^LaTeX Warning: Reference' $*.log; \ false; \ fi %-index.html: %.html $(AM_V_GEN)$(SPLITHTML) $(SPLITHTML_FLAGS) -o $@ $< SHOW_LATEX2HTML_LOG = \ rc=$$?; \ if $(AM_V_P); \ then \ cat $(1); \ else \ $(EGREP) '(Warning:|^Fixpoint)' $(1); \ fi; \ test $$rc -eq 0 %.html: $(srcdir)/%.tex $(AM_V_GEN)$(LATEX2HTML) $(LATEX2HTML_FLAGS) $< >$*.hlog 2>&1; \ $(call SHOW_LATEX2HTML_LOG,$*.hlog) %.cleantex.gp: $(srcdir)/%.gp $(AM_V_at)$(CLEANTEX) $^ > $@ %.png: %.cleantex.gp $(gnuplot_verbose)$(GNUPLOT) $(GNUPLOT_FLAGS) \ -e 'set output "$@"; set terminal pngcairo $(GNUPLOT_PNG_TERMINAL_OPTIONS)' $< # NOTE: `set output' gets the Encapsulated PostScript file's name # right. The `mv' command matches the LaTeX envelope's name to it. %.pstex: $(srcdir)/%.gp $(gnuplot_verbose)$(GNUPLOT) $(GNUPLOT_FLAGS) \ -e 'set output "$(basename $@).tex"; set terminal epslatex $(GNUPLOT_EPSLATEX_TERMINAL_OPTIONS)' $< && \ mv $(basename $@).tex $@ %.eps: $(srcdir)/%.dot $(dot_verbose)$(DOTPP) $(DOTPP_FLAGS) --define='dot_output_type=eps' $(DOTPP_PRELOAD) $< | \ $(DOT) $(DOT_FLAGS) -Teps $(DOT_EPS_FLAGS) -o$@ %.png: $(srcdir)/%.dot $(dot_verbose)$(DOTPP) $(DOTPP_FLAGS) --define='dot_output_type=png' $(DOTPP_PRELOAD) $< | \ $(DOT) $(DOT_FLAGS) -Tpng $(DOT_PNG_FLAGS) | \ $(CONVERT) png:- -transparent white -resize $$(( ((96 * 1000) / $(PRINT_RESOLUTION)) / 10 ))% $@ # ANTICIPATED CHANGE: Add a path via inkscape(1) # INKSCAPE = ... # %.pstex: $(srcdir)/%.svg # $(INKSCAPE) --without-gui --export-area-drawing --export-latex --export-eps=$(basename $@).eps --file=$< # mv $(basename $@).eps_tex $@ # Make the dependence on INKSCAPE optional, i.e. keep SVGCONVERT as # mandatory converter. %.eps: $(srcdir)/%.svg $(svgconvert_verbose)$(SVGCONVERT) $(SVGCONVERT_EPS_FLAGS) --output=$@ $< %.png: $(srcdir)/%.svg $(svgconvert_verbose)$(SVGCONVERT) $(SVGCONVERT_PNG_FLAGS) --output=$@ $< %.eps: $(srcdir)/%.tif $(convert_verbose)$(CONVERT) $< eps3:$@ %.png: $(srcdir)/%.tif $(convert_verbose)$(CONVERT) $< $@ %-version.tex: FORCE $(docstrings_verbose)$(DOCSTRINGS) key-value \ UPDATED '$(shell $(UPDATED_ON) $(UPDATED_ON_FLAGS) $(FILES))' \ VERSION '$(VERSION)' \ DOCDIR '$(docdir)' > $@ ######################################################################## DOCSTRING_SOURCE_FILES = \ $(wildcard \ $(addprefix $(srcdir)/../src/, \ *.h \ *.cc \ layer_selection/*.h \ layer_selection/*.cc)) config-h.tex: ../config.h $(config2tex_verbose)$(CONFIG2TEX) $< $@ dynamic-preamble.tex: FORCE $(AM_V_GEN) $(AM_V_at)printf '%%%%%% %s\n' '$(basename $@)' > $@ $(AM_V_at)printf '\PassOptionsToPackage{%spaper}{report}\n' '$(PAPERSIZE)' >> $@ $(AM_V_at)printf '\PassOptionsToPackage{%spaper}{refrep}\n' '$(PAPERSIZE)' >> $@ $(AM_V_at)printf '\\newif\ifreferencemanual\n' >> $@ $(AM_V_at)printf '\\newif\ifhyperref\n' >> $@ $(AM_V_at)printf '\\def\\documentclassoptions{}\n' >> $@ $(AM_V_at)printf '\\def\\finishdynamicpreamble{}\n' >> $@ $(AM_V_at)printf '%%%% User definitions follow...\n' >> $@ $(AM_V_at)printf '%s\n' '$(DYNAMIC_TEX_PREAMBLE)' >> $@ external-mask-workflow.eps focus-stack-decision-tree.eps photographic-workflow.eps \ external-mask-workflow.png focus-stack-decision-tree.png photographic-workflow.png: $(srcdir)/uml-dot.m4 entropy-cutoff.gp entropy.gp exposure-cutoff.gp exposure-weights.gp \ fullsine.gp gaussian.gp halfsine.gp laplacian-of-gaussian.gp \ log-transform.gp lorentzian.gp power.gp: colors.gp ######################################################################## ENBLEND_SOURCE_FILES = \ $(wildcard $(srcdir)/common-*.tex) \ $(wildcard $(srcdir)/enblend-*.tex) \ $(addprefix $(srcdir)/, \ enblend.tex \ static-preamble.tex lead-in.tex lead-out.tex \ index-def.tex index-use.tex \ macros.tex floatstyle-ruledbot.sty exemplar.hva \ htmlstyle.tex url-def.tex \ ) ENBLEND_HYBRID_MATERIAL = \ log-transform.gp ENBLEND_EXTRA_MATERIAL = \ external-mask-workflow.dot \ internal-enblend-flow.dot \ internal-optimizer-chain.dot \ photographic-workflow.dot \ \ seam-line-visualization.tif ENBLEND_GENERATED_FILES = \ config-h.tex \ dynamic-preamble.tex \ enblend-variables.tex \ enblend-version.tex ENBLEND_DVI_SEPARATE_PREREQUISITES = \ $(addsuffix .pstex,$(basename $(ENBLEND_HYBRID_MATERIAL))) \ $(addsuffix .eps,$(basename $(ENBLEND_EXTRA_MATERIAL))) enblend.pdf: LATEX_TRANSLATOR = $(PDFLATEX) enblend.dvi: LATEX_TRANSLATOR = $(LATEX) enblend.pdf enblend.dvi: \ $(ENBLEND_SOURCE_FILES) \ $(ENBLEND_GENERATED_FILES) \ $(ENBLEND_DVI_SEPARATE_PREREQUISITES) ENBLEND_HTML_SEPARATE_PREREQUISITES = \ $(addsuffix .png,$(basename $(ENBLEND_HYBRID_MATERIAL))) \ $(addsuffix .png,$(basename $(ENBLEND_EXTRA_MATERIAL))) enblend.html: \ $(ENBLEND_SOURCE_FILES) \ $(ENBLEND_GENERATED_FILES) \ $(ENBLEND_HTML_SEPARATE_PREREQUISITES) enblend-variables.tex: $(filter-out %/enfuse.h %/enfuse.cc,$(DOCSTRING_SOURCE_FILES)) $(docstrings_verbose)$(DOCSTRINGS) scan-files $^ > $@ enblend-version.tex: FILES = $(ENBLEND_SOURCE_FILES) ######################################################################## ENFUSE_SOURCE_FILES = \ $(wildcard $(srcdir)/common-*.tex) \ $(wildcard $(srcdir)/enfuse-*.tex) \ $(addprefix $(srcdir)/, \ enfuse.tex \ static-preamble.tex lead-in.tex lead-out.tex \ index-def.tex index-use.tex \ macros.tex floatstyle-ruledbot.sty exemplar.hva \ htmlstyle.tex url-def.tex \ ) ENFUSE_HYBRID_MATERIAL = \ entropy-cutoff.gp \ entropy.gp \ exposure-cutoff.gp \ exposure-weights.gp \ fullsine.gp \ gaussian.gp \ halfsine.gp \ laplacian-of-gaussian.gp \ log-transform.gp \ lorentzian.gp \ power.gp \ sharp-edge.gp \ smooth-edge.gp ENFUSE_EXTRA_MATERIAL = \ external-mask-workflow.dot \ focus-stack-decision-tree.dot \ photographic-workflow.dot \ \ local-analysis-window.svg ENFUSE_GENERATED_FILES = \ config-h.tex \ dynamic-preamble.tex \ enfuse-variables.tex \ enfuse-version.tex ENFUSE_DVI_SEPARATE_PREREQUISITES = \ $(addsuffix .pstex,$(basename $(ENFUSE_HYBRID_MATERIAL))) \ $(addsuffix .eps,$(basename $(ENFUSE_EXTRA_MATERIAL))) enfuse.pdf: LATEX_TRANSLATOR = $(PDFLATEX) enfuse.dvi: LATEX_TRANSLATOR = $(LATEX) enfuse.pdf enfuse.dvi: \ $(ENFUSE_SOURCE_FILES) \ $(ENFUSE_GENERATED_FILES) \ $(ENFUSE_DVI_SEPARATE_PREREQUISITES) ENFUSE_HTML_SEPARATE_PREREQUISITES = \ $(addsuffix .png,$(basename $(ENFUSE_HYBRID_MATERIAL))) \ $(addsuffix .png,$(basename $(ENFUSE_EXTRA_MATERIAL))) enfuse.html: \ $(ENFUSE_SOURCE_FILES) \ $(ENFUSE_GENERATED_FILES) \ $(ENFUSE_HTML_SEPARATE_PREREQUISITES) enfuse-variables.tex: $(filter-out %/enblend.h %/enblend.cc,$(DOCSTRING_SOURCE_FILES)) $(docstrings_verbose)$(DOCSTRINGS) scan-files $^ > $@ enfuse-version.tex: FILES = $(ENFUSE_SOURCE_FILES) ######################################################################## .PHONY: install-ps-local install-ps-local: ps-local @ $(MKDIR_P) $(psdir) $(install_verbose)$(INSTALL_DATA) enblend.ps enfuse.ps $(psdir) .PHONY: install-html-local install-html-local: html-local @ $(MKDIR_P) $(htmldir) $(install_verbose)$(INSTALL_DATA) \ $(sort \ enblend.html $(ENBLEND_HTML_SEPARATE_PREREQUISITES) \ enfuse.html $(ENFUSE_HTML_SEPARATE_PREREQUISITES) \ ) \ $(htmldir) .PHONY: install-pdf-local install-pdf-local: pdf-local @ $(MKDIR_P) $(pdfdir) $(install_verbose)$(INSTALL_DATA) enblend.pdf enfuse.pdf $(pdfdir) .PHONY: install-dvi-local install-dvi-local: dvi-local @ $(MKDIR_P) $(dvidir) $(install_verbose)$(INSTALL_DATA) \ $(sort \ enblend.dvi $(patsubst %.pstex,%.eps,$(ENBLEND_DVI_SEPARATE_PREREQUISITES)) \ enfuse.dvi $(patsubst %.pstex,%.eps,$(ENFUSE_DVI_SEPARATE_PREREQUISITES)) \ ) \ $(dvidir) .PHONY: install-split-html install-split-html: split-html @ $(MKDIR_P) $(htmldir) $(install_verbose)$(INSTALL_DATA) \ $(sort \ enblend-index.html enblend.css $(wildcard enblend[0-9][0-9][0-9].html) \ $(ENBLEND_HTML_SEPARATE_PREREQUISITES) \ enfuse-index.html enfuse.css $(wildcard enfuse[0-9][0-9][0-9].html) \ $(ENFUSE_HTML_SEPARATE_PREREQUISITES) \ $(wildcard *_motif.gif) \ ) \ $(htmldir) EXTRA_DIST = \ $(wildcard $(srcdir)/*.data) \ $(wildcard $(srcdir)/*.dot) \ $(wildcard $(srcdir)/*.gp) \ $(wildcard $(srcdir)/*.pm) \ $(wildcard $(srcdir)/*.svg) \ $(wildcard $(srcdir)/*.tex) \ $(wildcard $(srcdir)/*.tif) \ $(addprefix $(srcdir)/, \ uml-dot.m4 \ endoc.ist floatstyle-ruledbot.sty exemplar.hva \ cleantex config2tex docstrings updated-on \ ) enblend-enfuse-4.2/doc/Makefile.in0000644000175000017500000010466212676432431014025 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/_ac_latex_test.m4 \ $(top_srcdir)/m4/ac_latex_class.m4 \ $(top_srcdir)/m4/ac_latex_package.m4 \ $(top_srcdir)/m4/ac_prog_ar.m4 \ $(top_srcdir)/m4/ac_prog_latex.m4 \ $(top_srcdir)/m4/ac_type_sig_atomic_t.m4 \ $(top_srcdir)/m4/ax_boost_base.m4 \ $(top_srcdir)/m4/ax_cxx_as_const.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/ax_openmp.m4 \ $(top_srcdir)/m4/ax_prog_perl_modules.m4 \ $(top_srcdir)/m4/ax_with_prog.m4 $(top_srcdir)/m4/lrint.m4 \ $(top_srcdir)/m4/lrintf.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" VPATH = # must be empty to keep srcdir free of products ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONVERT = @CONVERT@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_IMPLEMENTATION = @DL_IMPLEMENTATION@ DOT = @DOT@ DVIPDF = @DVIPDF@ DVIPS = @DVIPS@ DYNAMIC_TEX_PREAMBLE = @DYNAMIC_TEX_PREAMBLE@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_LIBS = @EXTRA_LIBS@ GNUPLOT = @GNUPLOT@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_INLINE = @HAVE_INLINE@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LATEX = @LATEX@ LATEX2HTML = @LATEX2HTML@ LATEX2HTML_LIBDIR = @LATEX2HTML_LIBDIR@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ M4 = @M4@ MAKEINDEX = @MAKEINDEX@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ OPENEXR_LIBS = @OPENEXR_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SPLITHTML = @SPLITHTML@ STRIP = @STRIP@ SVGCONVERT = @SVGCONVERT@ TEXLOGANALYSER = @TEXLOGANALYSER@ VERSION = @VERSION@ VIGRAIMPEX_LIB = @VIGRAIMPEX_LIB@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ amsmath = @amsmath@ bindir = @bindir@ bold_extra = @bold_extra@ boretti_classesansparametre = @boretti_classesansparametre@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ color = @color@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enumitem = @enumitem@ exec_prefix = @exec_prefix@ float = @float@ footnote = @footnote@ graphicx = @graphicx@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hyperref = @hyperref@ hyphenat = @hyphenat@ ifpdf = @ifpdf@ includedir = @includedir@ index = @index@ infodir = @infodir@ install_sh = @install_sh@ latex = @latex@ latexsym = @latexsym@ libdir = @libdir@ libexecdir = @libexecdir@ listings = @listings@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ microtype = @microtype@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ ragged2e = @ragged2e@ refrep = @refrep@ report = @report@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shorttoc = @shorttoc@ srcdir = @srcdir@ suffix = @suffix@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ url = @url@ xstring = @xstring@ SUBDIRS = examples TEXINPUTS = .:$(LATEX2HTML_LIBDIR):$(srcdir): LATEX_FLAGS = -file-line-error -halt-on-error -interaction nonstopmode TEXLOGANALYSER_FLAGS = $(if $(subst cat,,$(TEXLOGANALYSER)),-hrt,) MAKEINDEX_FLAGS = $(if $(subst false,,$(AM_V_P)),,-q) PAPERSIZE = a4 PRINT_RESOLUTION = 600 DVIPS_FLAGS = -q -t $(PAPERSIZE) -D$(PRINT_RESOLUTION) -Z LATEX2HTML_FLAGS = -O -I . -I $(srcdir) -fix SPLITHTML_FLAGS = -tocbis GNUPLOT_FLAGS = --default-settings -e 'DATA_DIR="$(srcdir)"' GNUPLOT_PNG_TERMINAL_OPTIONS = enhanced transparent truecolor size 720,540 GNUPLOT_EPSLATEX_TERMINAL_OPTIONS = color size 4.5in,3.375in DOTPP = $(M4) DOTPP_FLAGS = --fatal-warnings --prefix-builtins --synclines DOTPP_PRELOAD = $(srcdir)/uml-dot.m4 DOT_FLAGS = DOT_EPS_FLAGS = -Gsize=4.75,8.5 DOT_PNG_FLAGS = -Gbgcolor=transparent -Gresolution=$(PRINT_RESOLUTION) SVGCONVERT_FLAGS = --dpi-x=96 --dpi-y=96 SVGCONVERT_EPS_FLAGS = $(SVGCONVERT_FLAGS) --format=eps SVGCONVERT_PNG_FLAGS = $(SVGCONVERT_FLAGS) --format=png CLEANTEX = $(srcdir)/cleantex CONFIG2TEX = $(srcdir)/config2tex DOCSTRINGS = $(srcdir)/docstrings UPDATED_ON = $(srcdir)/updated-on UPDATED_ON_FLAGS = \ --database=source-code-manager \ --override='none:\datebyunknown' \ --override='fs:\datebyfs' \ --override='scm:\datebyscm' ######################################################################## config2tex_verbose = $(config2tex_verbose_@AM_V@) config2tex_verbose_ = $(config2tex_verbose_@AM_DEFAULT_V@) config2tex_verbose_0 = @echo " CFG2TEX $@"; convert_verbose = $(convert_verbose_@AM_V@) convert_verbose_ = $(convert_verbose_@AM_DEFAULT_V@) convert_verbose_0 = @echo " CONVERT $@"; docstrings_verbose = $(docstrings_verbose_@AM_V@) docstrings_verbose_ = $(docstrings_verbose_@AM_DEFAULT_V@) docstrings_verbose_0 = @echo " DOCSTR $@"; dvips_verbose = $(dvips_verbose_@AM_V@) dvips_verbose_ = $(dvips_verbose_@AM_DEFAULT_V@) dvips_verbose_0 = @echo " DVIPS $@"; dot_verbose = $(dot_verbose_@AM_V@) dot_verbose_ = $(dot_verbose_@AM_DEFAULT_V@) dot_verbose_0 = @echo " DOT $@"; svgconvert_verbose = $(svgconvert_verbose_@AM_V@) svgconvert_verbose_ = $(svgconvert_verbose_@AM_DEFAULT_V@) svgconvert_verbose_0 = @echo " SVGCONV $@"; gnuplot_verbose = $(gnuplot_verbose_@AM_V@) gnuplot_verbose_ = $(gnuplot_verbose_@AM_DEFAULT_V@) gnuplot_verbose_0 = @echo " GNUPLOT $@"; install_verbose = $(install_verbose_@AM_V@) install_verbose_ = $(install_verbose_@AM_DEFAULT_V@) install_verbose_0 = @echo " INSTALL $@"; latex_verbose = $(call latex_verbose_@AM_V@,$(1)) latex_verbose_ = $(call latex_verbose_@AM_DEFAULT_V@,$(1)) latex_verbose_0 = @echo " LATEX [pass $(1)] $@"; makeindex_verbose = $(call makeindex_verbose_@AM_V@,$(1)) makeindex_verbose_ = $(call makeindex_verbose_@AM_DEFAULT_V@,$(1)) makeindex_verbose_0 = @echo " MKIDX [$(1)] $@"; ######################################################################## PS2PDF_FLAGS = -r$(PRINT_RESOLUTION) DVIPDF_FLAGS = -p $(PAPERSIZE) -r $(PRINT_RESOLUTION) -v SHOW_LATEX_LOG = \ rc=$$?; \ if $(AM_V_P) || test $$rc -ne 0; \ then \ cat $(1); \ else \ $(TEXLOGANALYSER) $(TEXLOGANALYSER_FLAGS) $(1); \ fi; \ test $$rc -eq 0 SHOW_LATEX2HTML_LOG = \ rc=$$?; \ if $(AM_V_P); \ then \ cat $(1); \ else \ $(EGREP) '(Warning:|^Fixpoint)' $(1); \ fi; \ test $$rc -eq 0 ######################################################################## DOCSTRING_SOURCE_FILES = \ $(wildcard \ $(addprefix $(srcdir)/../src/, \ *.h \ *.cc \ layer_selection/*.h \ layer_selection/*.cc)) ######################################################################## ENBLEND_SOURCE_FILES = \ $(wildcard $(srcdir)/common-*.tex) \ $(wildcard $(srcdir)/enblend-*.tex) \ $(addprefix $(srcdir)/, \ enblend.tex \ static-preamble.tex lead-in.tex lead-out.tex \ index-def.tex index-use.tex \ macros.tex floatstyle-ruledbot.sty exemplar.hva \ htmlstyle.tex url-def.tex \ ) ENBLEND_HYBRID_MATERIAL = \ log-transform.gp ENBLEND_EXTRA_MATERIAL = \ external-mask-workflow.dot \ internal-enblend-flow.dot \ internal-optimizer-chain.dot \ photographic-workflow.dot \ \ seam-line-visualization.tif ENBLEND_GENERATED_FILES = \ config-h.tex \ dynamic-preamble.tex \ enblend-variables.tex \ enblend-version.tex ENBLEND_DVI_SEPARATE_PREREQUISITES = \ $(addsuffix .pstex,$(basename $(ENBLEND_HYBRID_MATERIAL))) \ $(addsuffix .eps,$(basename $(ENBLEND_EXTRA_MATERIAL))) ENBLEND_HTML_SEPARATE_PREREQUISITES = \ $(addsuffix .png,$(basename $(ENBLEND_HYBRID_MATERIAL))) \ $(addsuffix .png,$(basename $(ENBLEND_EXTRA_MATERIAL))) ######################################################################## ENFUSE_SOURCE_FILES = \ $(wildcard $(srcdir)/common-*.tex) \ $(wildcard $(srcdir)/enfuse-*.tex) \ $(addprefix $(srcdir)/, \ enfuse.tex \ static-preamble.tex lead-in.tex lead-out.tex \ index-def.tex index-use.tex \ macros.tex floatstyle-ruledbot.sty exemplar.hva \ htmlstyle.tex url-def.tex \ ) ENFUSE_HYBRID_MATERIAL = \ entropy-cutoff.gp \ entropy.gp \ exposure-cutoff.gp \ exposure-weights.gp \ fullsine.gp \ gaussian.gp \ halfsine.gp \ laplacian-of-gaussian.gp \ log-transform.gp \ lorentzian.gp \ power.gp \ sharp-edge.gp \ smooth-edge.gp ENFUSE_EXTRA_MATERIAL = \ external-mask-workflow.dot \ focus-stack-decision-tree.dot \ photographic-workflow.dot \ \ local-analysis-window.svg ENFUSE_GENERATED_FILES = \ config-h.tex \ dynamic-preamble.tex \ enfuse-variables.tex \ enfuse-version.tex ENFUSE_DVI_SEPARATE_PREREQUISITES = \ $(addsuffix .pstex,$(basename $(ENFUSE_HYBRID_MATERIAL))) \ $(addsuffix .eps,$(basename $(ENFUSE_EXTRA_MATERIAL))) ENFUSE_HTML_SEPARATE_PREREQUISITES = \ $(addsuffix .png,$(basename $(ENFUSE_HYBRID_MATERIAL))) \ $(addsuffix .png,$(basename $(ENFUSE_EXTRA_MATERIAL))) EXTRA_DIST = \ $(wildcard $(srcdir)/*.data) \ $(wildcard $(srcdir)/*.dot) \ $(wildcard $(srcdir)/*.gp) \ $(wildcard $(srcdir)/*.pm) \ $(wildcard $(srcdir)/*.svg) \ $(wildcard $(srcdir)/*.tex) \ $(wildcard $(srcdir)/*.tif) \ $(addprefix $(srcdir)/, \ uml-dot.m4 \ endoc.ist floatstyle-ruledbot.sty exemplar.hva \ cleantex config2tex docstrings updated-on \ ) all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile all-local installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-local mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local \ distclean-tags dvi: dvi-recursive dvi-am: dvi-local html: html-recursive html-am: html-local info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-dvi-local install-exec-am: install-html: install-html-recursive install-html-am: install-html-local install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-pdf-local install-ps: install-ps-recursive install-ps-am: install-ps-local installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: pdf-local ps: ps-recursive ps-am: ps-local uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ check check-am clean clean-generic clean-local cscopelist-am \ ctags ctags-am distclean distclean-generic distclean-local \ distclean-tags distdir dvi dvi-am dvi-local html html-am \ html-local info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-dvi-local \ install-exec install-exec-am install-html install-html-am \ install-html-local install-info install-info-am install-man \ install-pdf install-pdf-am install-pdf-local install-ps \ install-ps-am install-ps-local install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am pdf-local ps ps-am ps-local tags tags-am uninstall \ uninstall-am .NOTPARALLEL: export TEXINPUTS ######################################################################## .PHONY: all-local all-local: ps-local html-local .PHONY: ps-local ps-local: enblend.ps enfuse.ps .PHONY: pdf-local pdf-local: enblend.pdf enfuse.pdf .PHONY: html-local html-local: enblend.html enfuse.html .PHONY: dvi-local dvi-local: enblend.dvi enfuse.dvi .PHONY: enblend enblend: enblend.ps enblend.html .PHONY: enfuse enfuse: enfuse.ps enfuse.html .PHONY: clean-local clean-local: - rm -f *.eps *.png *.pstex *.gp - rm -f *.{g,o,p,a}nd *.{g,o,p,a}dx - rm -f *.idx *.ilg *.ind *.lo{a,f,t,x} *.toc - rm -f *.aux *.log *.dvi *.ps *.pdf - rm -f *.html *.haux *.hind *.hlog - rm -f en*.{htoc,hpnd,hond,hgnd,haux,hand,hdgx} - rm -f enblend.out enblend.image.{tex,out} enblend-{variables,version}.tex - rm -f enfuse.out enfuse.image.{tex,out} enfuse-{variables,version}.tex - rm -f *_motif.gif - rm -f enblend{-index.html,.css,[0-9][0-9][0-9].html} - rm -f enfuse{-index.html,.css,[0-9][0-9][0-9].html} .PHONY: distclean-local distclean-local: clean-local - rm -f config-h.tex dynamic-preamble.tex - rm -f *~ .PHONY: FORCE .PHONY: split-html split-html: split-enblend-html split-enfuse-html .PHONY: split-enblend-html split-enblend-html: enblend-index.html .PHONY: split-enfuse-html split-enfuse-html: enfuse-index.html %.ps.pdf: %.ps $(AM_V_GEN)$(PS2PDF) $(PS2PDF_FLAGS) $< $@ %.dvi.pdf: %.dvi $(AM_V_GEN)$(DVIPDF) $(DVIPDF_FLAGS) -o $@ $< %.ps: %.dvi $(dvips_verbose)$(DVIPS) $(DVIPS_FLAGS) -o $@ $< %.dvi %.pdf: $(srcdir)/%.tex $(srcdir)/endoc.ist @- rm -f $(foreach ext,aux toc lo[^g] ?nd ?dx,$(basename $@).$(ext)) $(call latex_verbose,1)$(LATEX_TRANSLATOR) $(LATEX_FLAGS) $(EXTRA_LATEX_FLAGS) $< >/dev/null; \ $(call SHOW_LATEX_LOG,$*.log) $(call makeindex_verbose,general terms)$(MAKEINDEX) $(MAKEINDEX_FLAGS) -s $(srcdir)/endoc.ist -o $*.gnd $*.gdx $(call makeindex_verbose,command-line options)$(MAKEINDEX) $(MAKEINDEX_FLAGS) -o $*.ond $*.odx $(call makeindex_verbose,applications and programs)$(MAKEINDEX) $(MAKEINDEX_FLAGS) -o $*.pnd $*.pdx $(call makeindex_verbose,syntactic comments)$(MAKEINDEX) $(MAKEINDEX_FLAGS) -o $*.and $*.adx $(call latex_verbose,2)$(LATEX_TRANSLATOR) $(LATEX_FLAGS) $(EXTRA_LATEX_FLAGS) $< >/dev/null; \ $(call SHOW_LATEX_LOG,$*.log) @ max_iter=5; \ iter=2; \ while [ $$iter -le $$max_iter ] && \ $(GREP) '^LaTeX Warning: There were undefined references' $*.log >/dev/null && \ $(GREP) '^LaTeX Warning: Label(s) may have changed' $*.log >/dev/null; \ do \ iter=$$((iter + 1)); \ if $(AM_V_P); then :; else printf ' LATEX [pass %d] %s\n' $$iter $@; fi; \ $(LATEX_TRANSLATOR) $(LATEX_FLAGS) $(EXTRA_LATEX_FLAGS) $< >/dev/null; \ $(call SHOW_LATEX_LOG,$*.log); \ done; \ if [ $$iter -le $$max_iter ]; \ then \ printf 'Fixpoint reached in %i step(s)\n' $$iter; \ else \ printf 'Fixpoint NOT reached after %i steps; still undefined or loose labels\n' $$iter; \ $(GREP) '^LaTeX Warning: Reference' $*.log; \ false; \ fi %-index.html: %.html $(AM_V_GEN)$(SPLITHTML) $(SPLITHTML_FLAGS) -o $@ $< %.html: $(srcdir)/%.tex $(AM_V_GEN)$(LATEX2HTML) $(LATEX2HTML_FLAGS) $< >$*.hlog 2>&1; \ $(call SHOW_LATEX2HTML_LOG,$*.hlog) %.cleantex.gp: $(srcdir)/%.gp $(AM_V_at)$(CLEANTEX) $^ > $@ %.png: %.cleantex.gp $(gnuplot_verbose)$(GNUPLOT) $(GNUPLOT_FLAGS) \ -e 'set output "$@"; set terminal pngcairo $(GNUPLOT_PNG_TERMINAL_OPTIONS)' $< # NOTE: `set output' gets the Encapsulated PostScript file's name # right. The `mv' command matches the LaTeX envelope's name to it. %.pstex: $(srcdir)/%.gp $(gnuplot_verbose)$(GNUPLOT) $(GNUPLOT_FLAGS) \ -e 'set output "$(basename $@).tex"; set terminal epslatex $(GNUPLOT_EPSLATEX_TERMINAL_OPTIONS)' $< && \ mv $(basename $@).tex $@ %.eps: $(srcdir)/%.dot $(dot_verbose)$(DOTPP) $(DOTPP_FLAGS) --define='dot_output_type=eps' $(DOTPP_PRELOAD) $< | \ $(DOT) $(DOT_FLAGS) -Teps $(DOT_EPS_FLAGS) -o$@ %.png: $(srcdir)/%.dot $(dot_verbose)$(DOTPP) $(DOTPP_FLAGS) --define='dot_output_type=png' $(DOTPP_PRELOAD) $< | \ $(DOT) $(DOT_FLAGS) -Tpng $(DOT_PNG_FLAGS) | \ $(CONVERT) png:- -transparent white -resize $$(( ((96 * 1000) / $(PRINT_RESOLUTION)) / 10 ))% $@ # ANTICIPATED CHANGE: Add a path via inkscape(1) # INKSCAPE = ... # %.pstex: $(srcdir)/%.svg # $(INKSCAPE) --without-gui --export-area-drawing --export-latex --export-eps=$(basename $@).eps --file=$< # mv $(basename $@).eps_tex $@ # Make the dependence on INKSCAPE optional, i.e. keep SVGCONVERT as # mandatory converter. %.eps: $(srcdir)/%.svg $(svgconvert_verbose)$(SVGCONVERT) $(SVGCONVERT_EPS_FLAGS) --output=$@ $< %.png: $(srcdir)/%.svg $(svgconvert_verbose)$(SVGCONVERT) $(SVGCONVERT_PNG_FLAGS) --output=$@ $< %.eps: $(srcdir)/%.tif $(convert_verbose)$(CONVERT) $< eps3:$@ %.png: $(srcdir)/%.tif $(convert_verbose)$(CONVERT) $< $@ %-version.tex: FORCE $(docstrings_verbose)$(DOCSTRINGS) key-value \ UPDATED '$(shell $(UPDATED_ON) $(UPDATED_ON_FLAGS) $(FILES))' \ VERSION '$(VERSION)' \ DOCDIR '$(docdir)' > $@ config-h.tex: ../config.h $(config2tex_verbose)$(CONFIG2TEX) $< $@ dynamic-preamble.tex: FORCE $(AM_V_GEN) $(AM_V_at)printf '%%%%%% %s\n' '$(basename $@)' > $@ $(AM_V_at)printf '\PassOptionsToPackage{%spaper}{report}\n' '$(PAPERSIZE)' >> $@ $(AM_V_at)printf '\PassOptionsToPackage{%spaper}{refrep}\n' '$(PAPERSIZE)' >> $@ $(AM_V_at)printf '\\newif\ifreferencemanual\n' >> $@ $(AM_V_at)printf '\\newif\ifhyperref\n' >> $@ $(AM_V_at)printf '\\def\\documentclassoptions{}\n' >> $@ $(AM_V_at)printf '\\def\\finishdynamicpreamble{}\n' >> $@ $(AM_V_at)printf '%%%% User definitions follow...\n' >> $@ $(AM_V_at)printf '%s\n' '$(DYNAMIC_TEX_PREAMBLE)' >> $@ external-mask-workflow.eps focus-stack-decision-tree.eps photographic-workflow.eps \ external-mask-workflow.png focus-stack-decision-tree.png photographic-workflow.png: $(srcdir)/uml-dot.m4 entropy-cutoff.gp entropy.gp exposure-cutoff.gp exposure-weights.gp \ fullsine.gp gaussian.gp halfsine.gp laplacian-of-gaussian.gp \ log-transform.gp lorentzian.gp power.gp: colors.gp enblend.pdf: LATEX_TRANSLATOR = $(PDFLATEX) enblend.dvi: LATEX_TRANSLATOR = $(LATEX) enblend.pdf enblend.dvi: \ $(ENBLEND_SOURCE_FILES) \ $(ENBLEND_GENERATED_FILES) \ $(ENBLEND_DVI_SEPARATE_PREREQUISITES) enblend.html: \ $(ENBLEND_SOURCE_FILES) \ $(ENBLEND_GENERATED_FILES) \ $(ENBLEND_HTML_SEPARATE_PREREQUISITES) enblend-variables.tex: $(filter-out %/enfuse.h %/enfuse.cc,$(DOCSTRING_SOURCE_FILES)) $(docstrings_verbose)$(DOCSTRINGS) scan-files $^ > $@ enblend-version.tex: FILES = $(ENBLEND_SOURCE_FILES) enfuse.pdf: LATEX_TRANSLATOR = $(PDFLATEX) enfuse.dvi: LATEX_TRANSLATOR = $(LATEX) enfuse.pdf enfuse.dvi: \ $(ENFUSE_SOURCE_FILES) \ $(ENFUSE_GENERATED_FILES) \ $(ENFUSE_DVI_SEPARATE_PREREQUISITES) enfuse.html: \ $(ENFUSE_SOURCE_FILES) \ $(ENFUSE_GENERATED_FILES) \ $(ENFUSE_HTML_SEPARATE_PREREQUISITES) enfuse-variables.tex: $(filter-out %/enblend.h %/enblend.cc,$(DOCSTRING_SOURCE_FILES)) $(docstrings_verbose)$(DOCSTRINGS) scan-files $^ > $@ enfuse-version.tex: FILES = $(ENFUSE_SOURCE_FILES) ######################################################################## .PHONY: install-ps-local install-ps-local: ps-local @ $(MKDIR_P) $(psdir) $(install_verbose)$(INSTALL_DATA) enblend.ps enfuse.ps $(psdir) .PHONY: install-html-local install-html-local: html-local @ $(MKDIR_P) $(htmldir) $(install_verbose)$(INSTALL_DATA) \ $(sort \ enblend.html $(ENBLEND_HTML_SEPARATE_PREREQUISITES) \ enfuse.html $(ENFUSE_HTML_SEPARATE_PREREQUISITES) \ ) \ $(htmldir) .PHONY: install-pdf-local install-pdf-local: pdf-local @ $(MKDIR_P) $(pdfdir) $(install_verbose)$(INSTALL_DATA) enblend.pdf enfuse.pdf $(pdfdir) .PHONY: install-dvi-local install-dvi-local: dvi-local @ $(MKDIR_P) $(dvidir) $(install_verbose)$(INSTALL_DATA) \ $(sort \ enblend.dvi $(patsubst %.pstex,%.eps,$(ENBLEND_DVI_SEPARATE_PREREQUISITES)) \ enfuse.dvi $(patsubst %.pstex,%.eps,$(ENFUSE_DVI_SEPARATE_PREREQUISITES)) \ ) \ $(dvidir) .PHONY: install-split-html install-split-html: split-html @ $(MKDIR_P) $(htmldir) $(install_verbose)$(INSTALL_DATA) \ $(sort \ enblend-index.html enblend.css $(wildcard enblend[0-9][0-9][0-9].html) \ $(ENBLEND_HTML_SEPARATE_PREREQUISITES) \ enfuse-index.html enfuse.css $(wildcard enfuse[0-9][0-9][0-9].html) \ $(ENFUSE_HTML_SEPARATE_PREREQUISITES) \ $(wildcard *_motif.gif) \ ) \ $(htmldir) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: enblend-enfuse-4.2/doc/lead-out.tex0000644000175000017500000000123012632610324014166 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \cleardoublepage{} \vspace*{\fill} \begin{sgquote} \Quote{You have your answer,\genidx{Jackson, Daniel@\propername{Jackson, Daniel}} Daniel Jackson. I suggest you act on it.} -- \Author{\genidx{Morgan le Fay@\propername{Morgan le Fay}}% \gensee{Ganos Lal@\propername{Ganos Lal}}{\propername{Morgan le Fay}}% \propername{Morgan le Fay (Ganos Lal)}}% \end{sgquote} \vspace*{\fill} \appendix \input{common-helpful-programs} \input{common-bug-reports} \input{common-authors} \input{common-fdl} \input{index-use} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enfuse-exposure-weighting-user-dynamic.tex0000644000175000017500000005314612676423754022230 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \subsection[User-Defined Dynamic Functions]{\label{sec:user-defined-dynlink-functions}% \genidx{weighting!exposure!user-defined!dynamically-linked}% User-Defined, Dynamically-Linked Exposure Weighting Functions} %% -- Commented out for Stable Branch 4.2 %% -- Commented out for Stable Branch 4.2 %% See also \sectionName~\ref{sec:user-defined-opencl-functions} below on defining weighting %% functions via \acronym{OpenCL}. \restrictednote{\acronym{Dynamic Linking}-enabled versions only.} \genidx{linking!dynamic}% \gensee{dynamic linking}{linking, dynamic}% \genidx{loading!dynamic}% \gensee{dynamic loading}{loading, dynamic}% \genidx{shared object}% \gensee{object!shared}{shared object}% \genidx{dynamic library}% \gensee{library!dynamic}{dynamic library}% On operating systems, where dynamic linking (or synonymously: dynamic loading) of code is possible, for \App{} executables compiled with dynamic-linking support (see Section~\fullref{sec:finding-out-details} on how to check this feature), \App{} can work with user-defined exposure weighting functions, passed with the long form of option~\option{--exposure-weight-function}, load the exposure weight function identified by \metavar{SYMBOL} from \metavar{SHARED-OBJECT} and optionally pass some \metavar{ARGUMENT}s: \begin{literal} --exposure-weight-function=\metavar{SHARED-OBJECT}:\feasiblebreak \metavar{SYMBOL}\optional{:\feasiblebreak \metavar{ARGUMENT}\optional{:\dots}}% \optidx{--exposure-weight-function} \end{literal} Some notes on the arguments of this option: \begin{itemize} \item \metavar{SHARED-OBJECT} is a filename (typically ending in \filename{.so} or \filename{.dll}). Depending on the operating system and the dynamic-loader implementation compiled into \appcmd, \metavar{SHARED-OBJECT} may or may not require a path. \genidx{environment variable!LD\_LIBRARY\_PATH@\envvar{LD\_LIBRARY\_PATH}}% \gensee{LD\_LIBRARY\_PATH@\envvar{LD\_LIBRARY\_PATH}}% {environment variable, \envvar{LD\_LIBRARY\_PATH}}% \begin{restrictedmaterial}{Linux} If \metavar{SHARED-OBJECT} does not contain a slash (\sample{/}), the dynamic loader \emph{only} searches along \envvar{LD\_LIBRARY\_PATH}; it even ignores the current working directory unless \envvar{LD\_LIBRARY\_PATH} contains a dot (\sample{.}). So, to use a \metavar{SHARED-OBJECT} living in the current directory either say \begin{literal} env LD\_LIBRARY\_PATH=\$LD\_LIBRARY\_PATH:. \bslash \\ ~~~~\app{} --exposure-weight-function=\feasiblebreak SHARED-OBJECT:\dots \end{literal} or \begin{literal} \app{} --exposure-weight-function=\feasiblebreak ./SHARED-OBJECT:\dots \end{literal} \genidx{dlopen!Linux}% For details of the search algorithm please consult the manual page of \manpage{dlopen}{3}. \end{restrictedmaterial} \smallskip \genidx{environment variable!LD\_LIBRARY\_PATH@\envvar{LD\_LIBRARY\_PATH}}% \gensee{LD\_LIBRARY\_PATH@\envvar{LD\_LIBRARY\_PATH}}% {environment variable, \envvar{LD\_LIBRARY\_PATH}}% \genidx{environment variable!DYLD\_LIBRARY\_PATH@\envvar{DYLD\_LIBRARY\_PATH}}% \gensee{DYLD\_LIBRARY\_PATH@\envvar{DYLD\_LIBRARY\_PATH}}% {environment variable, \envvar{DYLD\_LIBRARY\_PATH}}% \genidx{environment variable!DYLD\_FALLBACK\_LIBRARY\_PATH@\envvar{DYLD\_FALLBACK\_LIBRARY\_PATH}}% \gensee{DYLD\_FALLBACK\_LIBRARY\_PATH@\envvar{DYLD\_FALLBACK\_LIBRARY\_PATH}}% {environment variable, \envvar{DYLD\_FALLBACK\_LIBRARY\_PATH}}% \begin{restrictedmaterial}{OS~X} \genidx{file!Mach-O}% \gensee{Math-O file}{file, Mach-O}% If \metavar{SHARED-OBJECT} does not contain a slash (\sample{/}), the dynamic loader searches the following paths or directories until it finds a compatible Mach-O~file: \begin{enumerate} \item \envvar{LD\_LIBRARY\_PATH}, \item \envvar{DYLD\_LIBRARY\_PATH}, \item current working directory, and finally \item \envvar{DYLD\_FALLBACK\_LIBRARY\_PATH}. \end{enumerate} \genidx{dlopen!OS~X}% For details of the search algorithm please consult the manual page of \manpage{dlopen}{3}. \end{restrictedmaterial} \smallskip \begin{restrictedmaterial}{Windows} If \metavar{SHARED-OBJECT} specifies an absolute filename, exactly this file is used. Otherwise \App{} searches in the following directories and in this order: \begin{enumerate} \item The directory from which \appcmd{} is loaded. \item The system directory. \item The Windows directory. \item The current directory. \item The directories that are listed in the \envvar{PATH}~environment variable. \end{enumerate} \genidx{LoadLibrary (Windows)}% For details consult the manual page of LoadLibrary. \end{restrictedmaterial} \item There is no way knowing which of the symbols inside of \metavar{SHARED-OB\shyp JECT} are suitable for \metavar{SYMBOL} without knowledge of source code of \metavar{SHARED-OBJECT}. \item A weight function has access to additional \metavar{ARGUMENT}s passed in by appending them after \metavar{SYMBOL} with the usual delimiters. How these \metavar{ARGUMENT}s are interpreted and how many of them are required is encoded in the weight-function. \App{} supports \metavar{ARGUMENT}s; it neither restricts their number nor their type. \begin{geeknote}% \optidx{--exposure-optimum}% \optidx{--exposure-width}% Usually, neither the exposure optimum (\option{--exposure-optimum}=\feasiblebreak\metavar{OPTIMUM}) nor the width (\option{--exposure-width}=\feasiblebreak\metavar{WIDTH}) of the exposure function are \metavar{ARGUMENT}s, because they are always explicitly passed on to any exposure weight function. \end{geeknote} For example, assuming \filename{variable\_power.cc} of the supplied examples was compiled to \filename{variable\_power.so}, we can override the default exponent of 2 with \begin{literal} \app{} --exposure-weight-function=\bslash \\ ~~~~~~~~~variable\_power.so:vpower:1.8 \dots \end{literal} \end{itemize} \subsubsection[Prerequisites]{\label{sec:prerequisites}% \genidx{weighting!exposure!prerequisites}% Prerequisites} To use a home-grown exposure-weight function several prerequisites must be met. On the software side \begin{enumerate} \item The operating system allows loading additional code during the execution of an application. \genidx{dynamic linking support}% \item \App{} is compiled with the extra feature ``dynamic linking support''. \item Either \begin{enumerate} \item The same compiler that compiled \App{} is available or at least \item A compiler that produces compatible object code to the compiler that compiled \App{}. \end{enumerate} The latter is called ``\acronym{ABI}-compatible''. An example for a pair of \acronym{ABI}-compatible compilers is \acronym{GNU}'s~\command{g++} and \propername{Intel's}~\command{icpc}. \optidx{--show-software-components}% To find out which compiler built \emph{your} version of \appcmd{} use option~\option{--show\hyp soft\shyp ware\hyp com\shyp po\shyp nents}. \item The base-class header file \filename{exposure\_weight\_base.h} is available. \end{enumerate} Between chair and keyboard: \begin{itemize} \item A firm understanding of weighting pixels in the fusion process and in particular in the cumulative ascription of different weights. \item A basic understanding of object-oriented programming paired with the ability to compile and link single-source C++-files. \item A realistic expectation of the limitations of tailoring weight functions. \end{itemize} \subsubsection[Coding Guidelines]{\label{sec:coding-guidelines}% \genidx{coding guidelines}% Coding Guidelines} \begin{enumerate} \item \begin{sloppypar} Derive the weight function from the supplied C++ base-class~\code{ExposureWeight}, which is defined in header file~\filename{exposure\_weight\_base.h}. It resides in the \filename{src}~sub-directory of the source distribution and -- for a correctly installed package -- in directory \filename{\val*{val:DOCDIR}\slash examples\slash enfuse}. \end{sloppypar} \item At least override method~\code{weight}. \begin{itemize} \item Domain: define \code{weight} for normalized luminance values~\metavar{y} from zero to one including both interval ends: $0 \le y \le 1$. \item Image: Let the \code{weight}~$w$ fall in the interval from zero to one: $0 \le w \le 1$. The \code{weight}s can be all the same, $w = \mbox{const}$. This is, they can encode a constant weight, as long as the constant is not zero. \App{} checks this property and refuses to continue if any weight is outside the required range or all weights are zero. \item (Optionally) Rescale the \metavar{WIDTH} of the function to match the \acronym{FWHM} of \App{}'s original Gauss curve. The macro~\code{FWHM\_GAUSSIAN} is defined exactly to this end. \end{itemize} \item If necessary, rewrite methods~\code{initialize} and \code{normalize}, too. \item \restrictednote{\acronym{OpenMP}-enabled versions only.} \App{} never calls \code{initialize} in an \acronym{OpenMP} parallel execution environment. However, \acronym{OpenMP}-enabled versions of \App{} call \code{normalize} and \code{weight} in parallel sections. Technically, the functors which the user-defined weight functions are part of are copy-constructed for each \acronym{OpenMP} worker thread. Thus, there is no contention within the \code{ExposureWeight} sub-classes. Although, if \code{normalize} or \code{weight} access a shared resource these accesses must be protected by serialization instructions. One solution is to use \acronym{OpenMP} directives, like for example, \begin{cxxlisting} #pragma omp critical { std::cout << "foobar!" << std::endl; } \end{cxxlisting} Experienced hackers will recognize occasions when to prefer other constructs, like, for example \code{\#pragma omp atomic} or simply an atomic data-type (e.g.~\code{sig\_atomic\_t} from \filename{signal.h}). Remember to compile all modules that use \acronym{OpenMP} directives with the (compiler-specific) flags that turn on \acronym{OpenMP}. For \command{g++} this is \sample{-fopenmp} and for \command{icpc} it is \sample{-fopenmp} or \sample{-openmp}. \item To raise an exception associated with the derived, user\hyp defined exposure\hyp weight class, throw \begin{literal} ExposureWeight::error(const std::string\& message) \end{literal} \App{} catches these exceptions at an enclosing scope, displays \metavar{message}, and aborts. \item Define an object of the derived class. This creates the \metavar{SYMBOL} to refer to at the \App{} command line. The actual signature of the constructor (default, two-argument, \dots) does not matter, because \App{} \emph{always} invokes \code{initialize} before calling any other method of a user-defined \code{ExposureWeight} sub-class. Method~\code{initialize} sets (read: overwrites) \metavar{optimum} and \metavar{width} and ensures they are within the required parameter range. \end{enumerate} \exampleName~\ref{ex:simple-dynamic-exposure-weight-function} shows the C++-code of a suitable extension. If \App{} has been compiled with support for user-defined weight functions, the examples presented here should have been duplicated in directory~\filename{\val*{val:DOCDIR}\slash examples\slash enfuse} along with a \acronym{GNU}-Makefile called \filename{Makefile.userweight}. \begin{exemplar} \begin{maxipage} \begin{cxxlisting} #include // std::fabs() #include "exposure_weight_base.h" // FWHM_GAUSSIAN, ExposureWeight struct Linear : public ExposureWeight { void initialize(double y_optimum, double width_parameter, ExposureWeight::argument_const_iterator arguments_begin, ExposureWeight::argument_const_iterator arguments_end) override { ExposureWeight::initialize(y_optimum, width_parameter * FWHM_GAUSSIAN, arguments_begin, arguments_end); } double weight(double y) override { const double z = std::fabs(normalize(y)); return z <= 1.0 ? 1.0 - z : 0.0; } }; Linear linear; \end{cxxlisting} \end{maxipage} \caption[Simple dynamic exposure weight function]% {\label{ex:simple-dynamic-exposure-weight-function}% A dynamic exposure weight function that defines a ``roof-top''. The natural width is exactly one, so we override method~\code{initialize} to rescale \metavar{WIDTH}, passed in as \code{width\_parameter}, by multiplying with \code{FWHM\_GAUSSIAN} to get the same width as the predefined Gaussian.} \end{exemplar} As the extension language is C++, we can write templated families of functions, like \exampleName~\ref{ex:templated-dynamic-exposure-weight-function} demonstrates. \begin{exemplar} \begin{maxipage} \begin{cxxlisting} #include // std::max() #include // M_LN2, std::exp(), std::fabs() #include "exposure_weight_base.h" // FWHM_GAUSSIAN, ExposureWeight template double ipower(double x) {return x * ipower(x);} template <> double ipower<0>(double) {return 1.0;} template struct TemplatedPower : public ExposureWeight { void initialize(double y_optimum, double width, ExposureWeight::argument_const_iterator arguments_begin, ExposureWeight::argument_const_iterator arguments_end) override { const double fwhm = 2.0 / std::exp(M_LN2 / static_cast(n)); ExposureWeight::initialize(y_optimum, width * FWHM_GAUSSIAN / fwhm, arguments_begin, arguments_end); } double weight(double y) override { return std::max(1.0 - ipower(std::fabs(normalize(y))), 0.0); } }; TemplatedPower<2> tpower2; TemplatedPower<3> tpower3; TemplatedPower<4> tpower4; \end{cxxlisting} \end{maxipage} \caption[Templated dynamic exposure weight function]% {\label{ex:templated-dynamic-exposure-weight-function}% The templated class~\code{TemplatedPower} allows to create a weight function for arbitrary positive exponents~\code{n}. In particular, \code{TemplatedPower<4>} duplicates the built-in exposure-weight function~\code{bisquare}.} \end{exemplar} The last example, \ref{ex:variable-dynamic-exposure-weight-function}, shows a weight function that accesses an extra \metavar{ARGUMENT} passed in with \option{--exposure-weight-function}. A class like \code{VariablePower} allows full control over the exponent at the command line including fractional exponents thereby generalizing both of the previous examples. \begin{exemplar} \begin{maxipage} \begin{cxxlisting} #include // std::max() #include // errno #include // M_LN2, std::exp(), std::fabs(), std::pow() #include "exposure_weight_base.h" // FWHM_GAUSSIAN, ExposureWeight class VariablePower : public ExposureWeight { typedef ExposureWeight super; public: void initialize(double y_optimum, double width, ExposureWeight::argument_const_iterator arguments_begin, ExposureWeight::argument_const_iterator arguments_end) override { if (arguments_begin == arguments_end) { exponent = 2.0; } else { char* tail; errno = 0; exponent = strtod(arguments_begin->c_str(), &tail); if (*tail != 0 || errno != 0) { throw super::error("non-numeric exponent"); } if (exponent <= 0.0 || exponent > 4.0) { throw super::error("exponent x out of range 0 < x <= 4"); } } const double fwhm = 2.0 / std::exp(M_LN2 / exponent); super::initialize(y_optimum, width * FWHM_GAUSSIAN / fwhm, arguments_begin, arguments_end); } double weight(double y) override { return std::max(1.0 - std::pow(std::fabs(normalize(y)), exponent), 0.0); } private: double exponent; }; VariablePower vpower; \end{cxxlisting} \end{maxipage} \caption[Dynamic exposure weight function with extra arguments]% {\label{ex:variable-dynamic-exposure-weight-function}% Dynamic exposure weight function that accesses the first extra argument from the tuple of arguments passed with option~\option{--exposure-weight-function}.} \end{exemplar} \subsubsection[Performance Considerations]{\label{sec:performance-considerations}% \genidx{performance considerations}% Performance Considerations} Exposure weighting objects are created and destroyed only $O(1)$~times. Thus, method~\code{initialize} could be used to perform all kinds of computationally expensive tasks. In contrast, methods~\code{normalize} and \code{weight} are called for \emph{every} pixel in \emph{each} of the input images. Therefore, if performance of the weight function is a problem, these two functions are the prime candidates for optimization. \subsubsection[Compiling, Linking, and Loading]{\label{sec:compiling-linking-loading}% Compiling, Linking, and Loading} \begin{restrictedmaterial}{Linux} \noindent Compile and link using the \uref{\gccgnuorg}{\acronym{GNU}-compiler}, \code{g++}, for example with \begin{literal} g++ -std=c++11 \bslash \\ ~~~~-O2 -fpic -I \bslash \\ ~~~~-shared -Wl,-soname,dynexp.so \bslash \\ ~~~~-o dynexp.so \bslash \\ ~~~~dynexp.cc \end{literal} The important options are \begin{codelist} \item[\option{-fpic}]\itemend Instruct the compiler's code-generator to produce position\hyp{}independent code (\acronym{PIC}), which is suitable for a shared object. Some systems require \sample{-fPIC} instead of \sample{-fpic}. \item[\option{-shared}]\itemend Tell the linker to create a shared object instead of the default executable. On some systems, the library must be ``blessed'', by passing the shared-object name (\option{soname}) directly to the linker (\option{-Wl}). Of course more than one object file can be linked into a single shared object. \end{codelist} Finally, the weight function can be selected by its \metavar{SYMBOL}~name in the \metavar{SHARED-OBJECT}. \begin{literal} \app{} --exposure-weight-function=dynexp.so:linear\dots \end{literal} \end{restrictedmaterial} \medskip \begin{restrictedmaterial}{OS~X} \noindent On OS~X the creation of shared objects -- or loadable modules -- has been tested with the C-language frontend of \uref{\llvm}{\acronym{LLVM}}, \uref{\clangllvm}{\code{clang++}}, and should work on OS~X Mavericks~(10.9) or higher. \begin{literal} clang++ -std=c++11 -stdlib=libc++ \bslash \\ ~~~~-O2 -bundle -I \bslash \\ ~~~~-o dynexp.so \bslash \\ ~~~~dynexp.cc \end{literal} The important option here is \sample{-bundle} which instructs the compiler's code-generator to produce a loadable module. Finally, the weight function can be selected by its \metavar{SYMBOL}~name in the \metavar{SHARED-OBJECT}. \begin{literal} \app{} --exposure-weight-function=dynexp.so:linear\dots \end{literal} \end{restrictedmaterial} \medskip \begin{restrictedmaterial}{Windows} \noindent On Windows the creation of shared objects -- or dynamic link libraries (\acronym{DLL}~files) as they are called here -- has been tested with the \acronym{MinGW} compiler chain and with MS-Visual~C++~2012. \begin{itemize} \item Compile and link using the \acronym{MinGW} compiler with \begin{literal} g++ -g -O2 -I -c dynexp.cc \\ g++ -g -shared -Wl,-soname,dynexp.dll -o dynexp.dll dynexp.o \end{literal} For details see the explanation for the \acronym{GNU} compiler above. Windows neither requires options \option{-fpic} nor~\option{-fPIC}. \item When using the MS-Visual~C++~compiler, you need to explicitly export \metavar{SYMBOL}. There are two possibilities to achieve this. Use only one variant, not both at the same time. \begin{enumerate} \item Either use \code{"C"}~linkage and define the object using the construction \code{\_\_declspec(dllexport)}. For \exampleName~\ref{ex:simple-dynamic-exposure-weight-function} the object definition has to be extended to \begin{cxxlisting} extern "C" { __declspec(dllexport) Linear linear; } \end{cxxlisting} \item Or, alternatively, create a module-definition file (\filename{.def}) and pass this file to the linker (in: \guielement{Project Properties}, \guielement{Linker}, \guielement{Module Definition File}). For \exampleName~\ref{ex:simple-dynamic-exposure-weight-function}, this file would look like \begin{literal} LIBRARY dynexp \\ EXPORTS \\ ~~~~~~~~linear @@1 \\ \end{literal} \end{enumerate} \end{itemize} Finally, the weight function can be selected by its \metavar{SYMBOL} in the dynamic link library. \begin{literal} \app{} --exposure-weight-function=dynexp.dll:linear\dots \end{literal} \end{restrictedmaterial} \begin{optionsummary} \item[--exposure-optimum] Section~\fullref{opt:exposure-optimum} \item[--exposure-weight-function] Section~\fullref{opt:exposure-weight-function} \item[--exposure-weight] Section~\fullref{opt:exposure-weight} \item[--exposure-width] Section~\fullref{opt:exposure-width} \item[--gray-projector] Section~\fullref{opt:gray-projector} \end{optionsummary} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/gaussian.gp0000644000175000017500000000100712566032753014110 00000000000000# Plot Gauss curve with default parameters of Enfuse default_optimum = 0.5 default_width = 0.2 gaussian(y, y_opt, width) = exp(-0.5 * ((y - y_opt) / width)**2) set key bmargin center horizontal set samples 1023 set xlabel "$Y$" set xtics 0.2 set ylabel "$w$" set ytics 0.2 load DATA_DIR . "/colors.gp" plot [y = 0:1] \ gaussian(y, default_optimum, 0.1) title "width = 0.1", \ gaussian(y, default_optimum, 0.2) title "default width = 0.2", \ gaussian(y, default_optimum, 0.4) title "width = 0.4" enblend-enfuse-4.2/doc/Quote.pm0000644000175000017500000000114412541464343013400 00000000000000# name: Quote.pm # synopsis: Put strings in quotes # author: Dr. Christoph L. Spiel # perl version: 5.20.2 # This file is part of Enblend. # Licence details can be found in the file COPYING. package Quote; use strict; use warnings; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(quote quote2 gnu_style); sub quote { my ($quote, @strings) = @_; map {qq($quote$_$quote)} @strings; } sub quote2 { my ($opening_quote, $closing_quote, @strings) = @_; map {qq($opening_quote$_$closing_quote)} @strings; } sub gnu_style { quote2(q(`), q('), @_); } 1; enblend-enfuse-4.2/doc/enfuse-expert-fusion-options.tex0000644000175000017500000006127712676175561020302 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \newcommand*{\metalowercutoff}{\metavar{LOWER\hyp{}CUT\shyp OFF}} \newcommand*{\metauppercutoff}{\metavar{UP\shyp PER\hyp{}CUT\shyp OFF}} \newcommand*{\metalowerprojector}{\metavar{LOWER\hyp{}PRO\shyp JEC\shyp TOR}} \newcommand*{\metaupperprojector}{\metavar{UP\shyp PER\hyp{}PRO\shyp JEC\shyp TOR}} \subsection[Expert Fusion Options]{\label{sec:expert-fusion-options}% \genidx[\rangebeginlocation]{expert fusion options}% \genidx{options!fusion for experts}% Expert Fusion Options} Expert fusion options control details of contrast-weight algorithms and they set ultimate cutoffs for entropy and exposure fusion. \begin{codelist} \label{opt:contrast-edge-scale}% \optidx[\defininglocation]{--contrast-edge-scale}% \genidx{Laplacian-of-Gaussian@\propername{Laplacian}-of-\propername{Gaussian}}% \gensee{LoG@\acronym{LoG}}{\propername{Laplacian}-of-\propername{Gaussian}}% \item[\itempar{--contrast-edge-scale=\metavar{EDGE-SCALE}\optional{:\feasiblebreak \metavar{LCE-SCALE}:\feasiblebreak\metavar{LCE-FACTOR}}}]\itemend A non-zero value for \metavar{EDGE-SCALE} switches on the \propername{Laplacian}\hyp{}of\hyp{}\propername{Gaussian} (\acronym{LoG}) edge detection algorithm. \metavar{EDGE-SCALE} is the radius of the \propername{Gaussian} used in the search for edges. Default: \val{val:default-edge-scale}~pixels. \genidx{contrast!local enhancement}% \gensee{local contrast enhancement}{contrast, local enhancement}% \gensee{LCE@\acronym{LCE}}{local contrast enhancement}% A positive \metavar{LCE-SCALE} turns on local contrast enhancement (\acronym{LCE}) before the \acronym{LoG} edge detection. \metavar{LCE-SCALE} is the radius of the \propername{Gaussian} used in the enhancement step, \metavar{LCE-FACTOR} is the weight factor (``strength''). \App{} calculates the \metavar{enhanced} values of the \metavar{original} ones with \begin{adalisting} enhanced := (1 + LCE-FACTOR) * original - LCE-FACTOR * GaussianSmooth(original, LCE-SCALE). \end{adalisting} \metavar{LCE-SCALE} defaults to \val{val:default-lce-scale}~pixels and \metavar{LCE-FACTOR} defaults to \val{val:default-lce-factor}. Append \sample{\%} to \metavar{LCE-SCALE} to specify the radius as a percentage of \metavar{EDGE-SCALE}. Append \sample{\%} to \metavar{LCE-FACTOR} to specify the weight as a percentage. \label{opt:contrast-min-curvature}% \optidx[\defininglocation]{--contrast-min-curvature}% \genidx{contrast!minimum curvature}% \item[--contrast-min-curvature=\metavar{CURVATURE}]\itemend Define the minimum \metavar{CURVATURE} for the \acronym{LoG} edge detection. Default: \val{val:default-minimum-curvature}. Append a \sample{\%} to specify the minimum curvature relative to maximum pixel value in the source image (for example 255 or~65535). A positive value makes \App{} use the local contrast data (controlled with option~\flexipageref{\option{--contrast-window-size}}{opt:contrast-window-size}) for curvatures less than \metavar{CURVATURE} and \acronym{LoG} data for values above it. A negative value truncates all curvatures less than $-\metavar{CURVATURE}$ to zero. Values above \metavar{CURVATURE} are left unchanged. This effectively suppresses weak edges. \label{opt:contrast-window-size}% \optidx[\defininglocation]{--contrast-window-size}% \genidx{contrast!window size}% \gensee{window size!contrast}{contrast, window size}% \item[--contrast-window-size=\metavar{SIZE}]\itemend Set the window \metavar{SIZE} for local contrast analysis. The window will be a square of $\metavar{SIZE} \times \metavar{SIZE}$~pixels. If given an even \metavar{SIZE}, \App{} will automatically use the next odd number. For contrast analysis \metavar{SIZE} values larger than 5~pixels might result in a blurry composite image. Values of 3 and~5~pixels have given good results on focus stacks. Valid range: $\metavar{SIZE} \geq \val{val:minimum-contrast-window-size}$, default: \val{val:default-contrast-window-size}~pixels. See also \sectionName~\fullref{sec:fusion-options}, options \flexipageref{\option{--contrast-weight}}{opt:contrast-weight} and \flexipageref{\option{--hard-mask}}{opt:hard-mask}. \label{opt:entropy-cutoff}% \optidx[\defininglocation]{--entropy-cutoff}% \genidx{entropy!cutoff}% \gensee{cutoff entropy}{entropy, cutoff}% \item[--entropy-cutoff=\metalowercutoff\optional{:\metauppercutoff{}}]\itemend Define a cutoff function~$Y'$ for the normalized luminance~$Y$ by \metalowercutoff{} and \metauppercutoff, which gets applied (only) before the local-entropy calculation. \metalowercutoff{} is the value below which pixels are mapped to pure black when calculating the local entropy of the pixel's surroundings. Optionally also define the \metauppercutoff{} value above which pixels are mapped to pure white. \begin{equation}\label{equ:luminance-entropy-cutoff} Y' = \left\{ \begin{array}{ll} 0 & \quad \mbox{for }Y \le \metalowercutoff, \\ 1 & \quad \mbox{for }Y \ge \metauppercutoff\mbox{ and} \\ Y & \quad \mbox{otherwise.} \end{array} \right. \end{equation} Also see \sectionName~\fullref{sec:local-entropy-weighting} for an explanation of local entropy. \figureName~\fullref{fig:entropy-cutoff} shows an example for the luminance mapping. Note that the entropy cutoff does not apply directly to the local-entropy~$H$ of a pixel or its weight~$w_H$, but the luminance image that get fed into the local-entropy weight calculation. However, assigning \emph{constant} values to extreme shadows or highlights in general decreases their local entropy, thereby reducing the pixels' weights. For color images \metalowercutoff{} and \metauppercutoff{} are applied separately and independently to each channel. Append a \sample{\%}-sign to specify the cutoff relative to maximum pixel value in the source image (for example 255 or~65535). Negative \metauppercutoff{} values indicate the maximum minus the absolute \metauppercutoff{} value; the same holds for negative percentages. Defaults: \val{val:default-entropy-lower-cutoff} for \metalowercutoff{} and \val{val:default-entropy-upper-cutoff} for \metauppercutoff, that is, all pixels' values are taken into account. \begin{figure} \begin{maxipage} \centering \includeimage{entropy-cutoff} \end{maxipage} \caption[Entropy cutoff function]{\label{fig:entropy-cutoff}% Modified lightness~$Y'$, \equationabbr~\ref{equ:luminance-entropy-cutoff}, for $\metalowercutoff = 5\%$ and $\metauppercutoff = 90\%$, which are rather extreme values.} \end{figure} \begin{geeknote} Note that a high \metalowercutoff{} value lightens the resulting image, as dark and presumably noisy pixels are averaged with \emph{equal} weights. With $\metalowercutoff = 0$, the default, on the other hand, ``noise'' might be interpreted as high entropy and the noisy pixels get a high weight, which in turn renders the resulting image darker. Analogously, a low \metauppercutoff{} darkens the output image. \end{geeknote} \label{opt:entropy-window-size}% \optidx[\defininglocation]{--entropy-window-size}% \genidx{entropy!window size}% \gensee{window size!entropy}{entropy, window size}% \item[--entropy-window-size=\metavar{SIZE}]\itemend Window \metavar{SIZE} for local entropy analysis. The window will be a square of $\metavar{SIZE} \times \metavar{SIZE}$~pixels. In the entropy calculation \metavar{SIZE} values of 3 to~7 yield an acceptable compromise of the locality of the information and the significance of the local entropy value itself. Valid range: $\metavar{SIZE} \geq \val{val:minimum-entropy-window-size}$, default: \val{val:default-entropy-window-size}~pixels. If given an even \metavar{SIZE} \App{} will automatically use the next-larger odd number. \label{opt:exposure-cutoff}% \optidx[\defininglocation]{--exposure-cutoff}% \genidx{exposure!cutoff}% \gensee{cutoff!exposure}{exposure, cutoff}% \item[\itempar{--exposure-cutoff=\metalowercutoff\optional{:\feasiblebreak \metavar{UPPER\hyp{}CUTOFF}\optional{:\feasiblebreak \metalowerprojector:\feasiblebreak \metaupperprojector}}}]\itemend Define an exposure-cutoff function by the luminances \metalowercutoff{} and \metauppercutoff. Pixels below the lower or above the upper cutoff get a weight of exactly zero irrespective of the active exposure-weight function. For color images the values of \metalowercutoff{} and \metauppercutoff{} refer to the gray-scale projection as selected with \metalowerprojector{} and \metaupperprojector. This is similar to option~\option{--gray\hyp{}pro\shyp jec\shyp tor}. Append a \sample{\%}-sign to specify the cutoff relative to maximum pixel value in the source image (for example 255 or~65535). Negative \metauppercutoff{} values indicate the maximum minus the absolute \metauppercutoff{} value; the same holds for negative percentages. \begin{geeknote} The impact of this option is similar, but not identical to transforming \emph{all} input images with \uref{\imagemagickorg}{ImageMagick's}\appidx{ImageMagick} \command{convert}\prgidx{convert} (see \appendixName~\fullref{sec:helpful-programs}) prior to fusing with the commands demonstrated in \exampleName~\ref{ex:imagemagick-convert-cutoff}. \begin{exemplar} \begin{terminal} \$ convert IMAGE \bslash \\ ~~~~~~~~~~~\bslash( +clone -threshold LOWER-CUTOFF \bslash) \bslash \\ ~~~~~~~~~~~-compose copy\_opacity -composite \bslash \\ ~~~~~~~~~~~MASKED-IMAGE \end{terminal} \smallskip \begin{terminal} \$ convert IMAGE \bslash \\ ~~~~~~~~~~~\bslash( \bslash \\ ~~~~~~~~~~~~~~~\bslash( IMAGE -threshold LOWER-CUTOFF \bslash) \bslash \\ ~~~~~~~~~~~~~~~\bslash( IMAGE -threshold UPPER-CUTOFF -negate \bslash) \bslash \\ ~~~~~~~~~~~~~~~-compose multiply -composite \bslash \\ ~~~~~~~~~~~\bslash) \bslash \\ ~~~~~~~~~~~-compose copy\_opacity -composite \bslash \\ ~~~~~~~~~~~MASKED-IMAGE \end{terminal} \caption[\application{ImageMagick} for exposure cutoff]% {\label{ex:imagemagick-convert-cutoff}% Using \application{ImageMagick} for exposure cutoff operations. The first example only applies a lower cutoff, whereas the second one applies both a lower and an upper cutoff to the images.} \end{exemplar} Transforming some or all input images as shown in the example gives the user more flexibility because the thresholds can be chosen for each image individually. \end{geeknote} The option allows to specify projection operators as in option~\option{--gray\hyp{}pro\shyp jec\shyp tor} for the \metalowercutoff{} and \metauppercutoff{} thresholds. This option can be helpful if the user wants to exclude underexposed or overexposed pixels from the fusing process in \emph{all} of the input images. The values of \metalowercutoff{} and \metauppercutoff{} as well as the gray-scale projector determine which pixels are considered ``underexposed'' or ``overexposed''. As any change of the exposure-weight curve this option changes the brightness of the resulting image: increasing \metalowercutoff{} lightens the final image and lowering \metauppercutoff{} darkens it. Defaults: \val{val:default-exposure-lower-cutoff} for \metalowercutoff{} and \val{val:default-exposure-upper-cutoff} for \metauppercutoff, that is, all pixels' values are weighted according to the ``uncut'' exposure-weight curve. \figureName~\ref{fig:exposure-cutoff} shows an example. The gray-scale projectors \metalowerprojector{} and \metaupperprojector{} default to \sample{\val{val:default-exposure-lower-cutoff-projector}} and \sample{\val{val:default-exposure-upper-cutoff-projector}}, which are usually the best choices for effective cutoff operations on the respective ends. \begin{figure} \begin{maxipage} \centering \includeimage{exposure-cutoff} \end{maxipage} \caption[Exposure cutoff function]{\label{fig:exposure-cutoff}% Exposure weight~$w_Y$ after an exposure-cutoff of $\metalowercutoff = 5\%$ and $\metauppercutoff = 97\%$ was applied to a \propername{Gaussian} with the $\metavar{optimum} = 0.5$ and $\metavar{width} = 0.2$.} \end{figure} Note that the application of the respective cutoffs is completely independent of the actual shape of the exposure weight function. If a set of images stubbornly refuses to ``react'' to this option, look at their histograms to verify the cutoff actually falls into populated ranges of the histograms. In the absence of an image manipulation program like \uref{\gimporg}{\application{The Gimp}}\appidx{Gimp}, \uref{\imagemagickorg}{ImageMagick's}\appidx{ImageMagick} can be used to generate \uref{\imagemagickorgusagefileshistogram}{histograms}, like, for example, \begin{terminal} \$ convert -define histogram:unique-colors=false \bslash \\ ~~~~~~~~~~~IMAGE histogram:- | \bslash \\ ~~~~~~~display \end{terminal} The syntax of this option is flexible enough to combine ease of use and precision, as \tableName~\ref{tab:flexible-exposure-cutoff} demonstrates. \begin{table} \begin{maxipage} \begin{tabular}{p{.3\linewidth}lp{.3\linewidth}} \hline \multicolumn{1}{c|}{Task} & \multicolumn{1}{c|}{Cutoff Setting} & \multicolumn{1}{c}{Effect} \\ \hline\extraheadingsep Suppress some noise. & \option{--exposure-cutoff=5\%} & The percentage makes the cutoff specification channel-width agnostic. \\ Shave off pure white pixels. & \option{--exposure-cutoff=0:-1} & This cutoff specification only works for integral pixels, but it will set the weight of the very brightest pixels to zero. \\ Shave off bright white pixels. & \option{--exposure-cutoff=0:-1\%} & Here we exclude the brightest 1\% of pixels form the exposure fusion no matter whether the image is encoded with integers or floating-point numbers. \\ Suppress some noise and shave off pure white pixels. & \option{--exposure-cutoff=5\%:-1} & Combine the effects of lower and upper cutoff, while mixing relative and absolute specifications. \end{tabular} \end{maxipage} \caption[Flexible exposure cutoff]{\label{tab:flexible-exposure-cutoff}% Some possible exposure-cutoff settings and their effects on the exposure weights.} \end{table} \label{opt:exposure-weight-function}% \optidx[\defininglocation]{--exposure-weight-function}% \genidx{weight!function!exposure}% \gensee{exposure weight!function}{weight, function, exposure}% \item[\itempar{--exposure-weight-function=\metavar{WEIGHT-FUNCTION}~\textrm{(\oldstylefirst~form)} \\ --exposure-weight-function=\metavar{SHARED-OBJECT}:\feasiblebreak \metavar{SYMBOL}\optional{:\feasiblebreak \metavar{ARGUMENT}\optional{:\dots}}~\textrm{(\oldstylesecond~form)}}]\itemend \oldstylefirst~form: override the default exposure weight function (\code{\val{val:exposure-weight-function}}) and instead use one of the weight-functions in \tableName~\fullref{tab:exposure-weight-functions}. \genidx{shared object}% \gensee{object!shared}{shared object}% \begin{restrictedmaterial}{Versions with dynamic-linking support only.} \noindent \oldstylesecond~form: dynamically load \metavar{SHARED-OBJECT} and use \metavar{SYMBOL} as user-defined exposure weight function. Optionally pass the user-defined function \metavar{ARGUMENT}s. \genidx{dynamic library}% \gensee{library!dynamic}{dynamic library}% \begin{geeknote} Depending on the operating system environment, a ``shared object'' is sometimes also called a ``dynamic library''. \end{geeknote} \end{restrictedmaterial} \genidx{exposure weight!linear transform}% In \tableName~\ref{tab:exposure-weight-functions} the variable~$w_{\mathrm{exp}}$ denotes the exposure weight and $z$ represents the normalized luminance~$Y$ linearly transformed by the exposure optimum~$Y_{\mathrm{opt}}$ (option~\option{--exposure-optimum}) and \metavar{width} (option~\option{--exposure-width}) according to the linear transform \begin{equation}\label{equ:linear-luminance-transform} z = \frac{Y - Y_{\mathrm{opt}}}{\mathit{width}}. \end{equation} \genidx{exposure weight function!full width half maximum}% \genidx{exposure weight function!\acronym{FWHM}}% \genidx{full width half maximum}% \gensee{FWHM@\acronym{FWHM}}{full width half maximum}% Internally \App{} uses a rescaled \metavar{width} that gives all weight functions the same full width at half of the maximum (\acronym{FWHM}), also see \figureName~\ref{fig:exposure-weights}. This means for the user that changing the exposure function neither changes the optimum exposure nor the width. \begin{table} \begin{codelist} \genidx{exposure weight function!gauss}% \genidx{exposure weight function!gaussian}% \item[\itempar{gauss \\ gaussian}]\itemend The original exposure weight function of \App{} and the only one up to version~4.1. \begin{equation}\label{equ:weight:gauss} w_{\mathrm{exp}} = \exp\left({-z^2 / 2}\right) \end{equation} \genidx{exposure weight function!lorentz}% \genidx{exposure weight function!lorentzian}% \item[\itempar{lorentz \\ lorentzian}]\itemend Lorentz curve. \begin{equation}\label{equ:weight:lorentz} w_{\mathrm{exp}} = \frac{1}{1 + z^2 / 2} \end{equation} \genidx{exposure weight function!halfsine}% \genidx{exposure weight function!half-sine}% \item[\itempar{halfsine \\ half-sine}]\itemend Upper half-wave of a sine; exactly zero outside. \begin{equation}\label{equ:weight:halfsine} w_{\mathrm{exp}} = \left\{\begin{array}{cl} \cos(z) & \mbox{if } |z| \leq \pi/2 \\ 0 & \mbox{otherwise.} \end{array}\right. \end{equation} \genidx{exposure weight function!fullsine}% \genidx{exposure weight function!full-sine}% \item[\itempar{fullsine \\ full-sine}]\itemend Full sine-wave shifted upwards by one to give all positive weights; exactly zero outside. \begin{equation}\label{equ:weight:fullsine} w_{\mathrm{exp}} = \left\{\begin{array}{cl} (1 + \cos(z)) / 2 & \mbox{if } |z| \leq \pi \\ 0 & \mbox{otherwise.} \end{array} \right. \end{equation} \genidx{exposure weight function!bisquare}% \genidx{exposure weight function!bi-square}% \item[\itempar{bisquare \\ bi-square}]\itemend Quartic function. \begin{equation}\label{equ:weight:bisquare} w_{\mathrm{exp}} = \left\{ \begin{array}{cl} 1 - z^4 & \mbox{if } |z| \leq 1 \\ 0 & \mbox{otherwise.} \end{array} \right. \end{equation} \end{codelist} \caption[Exposure weight functions]{\label{tab:exposure-weight-functions}% \genidx[\summarylocation]{exposure weight function}% Predefined exposure weight functions. For a graphical comparison see \figureName~\ref{fig:exposure-weights}.} \end{table} For a detailed explanation of all the weight functions \sectionName~\fullref{sec:exposure-weighting}. If this option is given more than once, the last instance wins. \label{opt:gray-projector}% \optidx[\defininglocation]{--gray-projector}% \genidx{gray projector}% \gensee{projector to grayscale}{gray projector}% \item[--gray-projector=\metavar{PROJECTOR}]\itemend Use gray projector~\metavar{PROJECTOR} for conversion of \acronym{RGB} images to grayscale: \[ (R, G, B) \rightarrow Y. \] In this version of \App{}, the option is effective for exposure weighting and local contrast weighting and \metavar{PROJECTOR} defaults to \sample{\val{val:default-grayscale-accessor}}. Valid values for \metavar{PROJECTOR} are: \begin{codelist} \genidx{gray projector!anti-value@\code{anti-value}}% \gensee{anti-value gray projector@\code{anti-value} gray projector}% {gray projector, \code{anti-value}}% \item[anti-value]\itemend Do the opposite of the \sample{value} projector: take the minimum of all color channels. \[ Y = \min(R, G, B) \] This projector can be useful when exposure weighing while employing a lower cutoff (see option~\option{--exposure-cutoff}) to reduce the noise in the fused image. \genidx{gray projector!average@\code{average}}% \gensee{average gray projector@\code{average} gray projector}% {gray projector, \code{average}}% \item[average]\itemend Average red, green, and blue channel with equal weights. This is the default, and it often is a good projector for $\mbox{gamma} = 1$ data. \[ Y = \frac{R + G + B}{3} \] \genidx{gray projector!channel-mixer@\code{channel-mixer}}% \gensee{channel-mixer gray projector@\code{channel-mixer} gray projector}% {gray projector, \code{channel-mixer}}% \item[\itempar{channel-mixer:\metavar{RED-WEIGHT}:\feasiblebreak \metavar{GREEN-WEIGHT}:\feasiblebreak\metavar{BLUE-WEIGHT}}]\itemend Weight the channels as given. \[ \begin{array}{r@{\hspace{1ex}}c@{\hspace{1ex}}l@{\hspace{1ex}}c@{\hspace{1ex}}cc} Y & = & \metavar{RED-WEIGHT} & \times & R & + \\ & & \metavar{GREEN-WEIGHT} & \times & G & + \\ & & \metavar{BLUE-WEIGHT} & \times & B & \end{array} \] The weights are automatically normalized to one, so \begin{literal} --gray-projector=channel-mixer:0.25:0.5:0.25 \\ --gray-projector=channel-mixer:1:2:1 \\ --gray-projector=channel-mixer:25:50:25 \end{literal} all define the same mixer configuration. The three weights \metavar{RED-WEIGHT}, \metavar{GREEN\hyp{}WEIGHT}, and \metavar{BLUE\hyp{}WEIGHT} define the relative weight of the respective color channel. The sum of all weights is normalized to one. \genidx{gray projector!l-star@\code{l-star}}% \gensee{l-star gray projector@\code{l-star} gray projector}% {gray projector, \code{l-star}}% \genidx{RGB-L*a*b* conversion@\acronym{RGB}-\acronym{L*a*b*} conversion}% \gensee{conversion!RGB-L*a*b*@\acronym{RGB}-\acronym{L*a*b*}}% {\acronym{RGB}-\acronym{L*a*b*} conversion}% \item[l-star]\itemend Use the L-channel of the L*a*b*-conversion of the image as its grayscale representation. This is a useful projector for $\mbox{gamma} = 1$ data. It reveals minute contrast variations even in the shadows and the highlights. This projector is computationally expensive. Compare with \sample{pl-star}, which is intended for gamma-corrected images. See \uref{\wikipedialabcolorspace}{Wikipedia} for a detailed description of the \acronym{Lab}~color space. \genidx{gray projector!lightness@\code{lightness}}% \gensee{lightness gray projector@\code{lightness} gray projector}% {gray projector, \code{lightness}}% \item[lightness]\itemend Compute the lightness of each \acronym{RGB} pixel as in an Hue\hyp{}Saturation\hyp{}Lightness (\acronym{HSL}) conversion of the image. \[ Y = \frac{\max(R, G, B) + \min(R, G, B)}{2} \] \genidx{gray projector!luminance@\code{luminance}}% \gensee{luminance gray projector@\code{luminance} gray projector}% {gray projector, \code{luminance}}% \item[luminance]\itemend Use the weighted average of the \acronym{RGB} pixel's channels as defined by \acronym{CIE} (``Commission Internationale de l'\'Eclairage'') and the \acronym{JPEG} standard. \[ Y = 0.30 \times R + 0.59 \times G + 0.11 \times B \] \genidx{gray projector!pl-star@\code{pl-star}}% \gensee{pl-star gray projector@\code{pl-star} gray projector}% {gray projector, \code{pl-star}}% \genidx{RGB'-L*a*b* conversion@\acronym{RGB'}-\acronym{L*a*b*} conversion}% \item[pl-star]\itemend Use the L-channel of the L*a*b*-conversion of the image as its grayscale representation. This is a useful projector for gamma-corrected data. It reveals minute contrast variations even in the shadows and the highlights. This projector is computationally expensive. Compare with \sample{l-star}, which is intended for $\mbox{gamma} = 1$ images. See \uref{\wikipedialabcolorspace}{Wikipedia} for a detailed description of the \acronym{Lab}~color space. \genidx{gray projector!value@\code{value}}% \gensee{value gray projector@\code{value} gray projector}{gray projector, \code{value}}% \item[value]\itemend Take the Value-channel of the Hue-Saturation-Value (\acronym{HSV}) conversion of the image. \[ Y = \max(R, G, B) \] \end{codelist} \end{codelist} \genidx[\rangeendlocation]{expert fusion options} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/sharp-edge.gp0000644000175000017500000000034612566032753014322 00000000000000# Plot an example of a particularly sharp edge set contour set grid set hidden3d set style data line set view 60, 30 set xtics 0, 1, 4 set ytics 0, 1, 4 unset key splot DATA_DIR . "/sharp-edge.data" matrix title "sharp edge" enblend-enfuse-4.2/doc/common-workflow.tex0000644000175000017500000000153012673203106015620 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Workflow\commonpart]{\label{sec:photographic-workflow}% \genidx[\rangebeginlocation]{photographic workflow}% \gensee{workflow}{photographic workflow}% Photographic Workflow\commonpart} \App{} and \OtherApp{} are parts of a chain of tools to assemble images. \begin{itemize} \item \application{Enblend} combines a series of pictures taken at the same location but in different directions. \item \application{Enfuse} merges photos of the same subject at the same location and same direction, but taken with varying exposure parameters. \end{itemize} \input{common-standard-workflow} \input{common-external-masks} \input{common-interaction} \genidx[\rangeendlocation]{photographic workflow} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enfuse-overview.tex0000644000175000017500000001346312676175561015641 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Overview]{\label{sec:overview}% \genidx[\rangebeginlocation]{overview}% Overview} \genidx{Mertens@\propername{Mertens, Tom}}% \genidx{Kautz@\propername{Kautz, Jan}}% \genidx{Reeth@\propername{Van Reeth, Frank}}% \genidx{fusion!exposure}% \gensee{exposure fusion}{fusion, exposure}% \genidx{high dynamic range}% \gensee{HDR@\acronym{HDR}}{high dynamic range}% \begin{sloppypar} \App{} merges overlapping images using the \propername{Mertens}-\propername{Kautz}\-\propername{Van Reeth} exposure fusion algorithm.\footnotemark{} This is a quick way for example to blend differently exposed images into a nice output image, without producing intermediate high-dynamic range (\acronym{HDR}) images that are then tone-mapped to a viewable image. This simplified process often works much better than tone-mapping algorithms.% % \footnotetext{\propername{Tom Mertens}, \propername{Jan Kautz}, and \propername{Frank van Reeth}, ``Exposure Fusion'', Proceedings of the 15$^{\mathrm{th}}$ Pacific Conference on Computer Graphics and Applications 2007, pages~382--390.} \end{sloppypar} \genidx{depth-of-field}% \gensee{DoF@\acronym{DoF}}{depth-of-field}% \App{} can also be used to build extended depth-of-field (\acronym{DoF}) images by blending a focus stack. The idea is that pixels in the input images are weighted according to qualities such as, for example, proper exposure, good local contrast, or high saturation. These weights determine how much a given pixel will contribute to the final image. \genidx{Burt@\propername{Burt, Peter J.}}% \genidx{Adelson@\propername{Adelson, Edward H.}}% \genidx{Burt-Adelson@\propername{Burt-Adelson}}% \genidx{multi-resolution spline}% \gensee{spline}{multi-resolution spline}% A \propername{Burt}-\propername{Adelson} multi-resolution spline blender\footnotemark{} is used to combine the images according to the weights. The multi-resolution blending ensures that transitions between regions where different images contribute are difficult to spot.% % \footnotetext{\propername{Peter J. Burt} and \propername{Edward H. Adelson}, ``A Multiresolution Spline With Application to Image Mosaics'', \acronym{ACM} Transactions on Graphics, \abbreviation{Vol}.~2, \abbreviation{No}.~4, October~1983, pages~217--236.} \App{} uses up to four criteria to judge the quality of a pixel: \begin{description} \genidx{weighting!exposure}% \gensee{exposure weighting}{weighting, exposure}% \item[Exposure]\itemend The exposure criteria favors pixels with luminance close to the middle of the range. These pixels are considered better exposed than those with high or low luminance levels. \genidx{weighting!saturation}% \gensee{saturation weighting}{weighting, saturation}% \item[Saturation]\itemend The saturation criteria favors highly-saturated pixels. Note that saturation is only defined for color pixels. \genidx{weighting!local contrast}% \gensee{contrast weighting}{weighting, local contrast}% \gensee{local contrast weighting}{weighting, local contrast}% \item[Local Contrast]\itemend The contrast criteria favors pixels inside a high-contrast neighborhood. \App{} can use standard deviation, \propername{Laplacian} magnitude, or a blend of both as local contrast measure. \genidx{weighting!local entropy}% \gensee{entropy weighting}{weighting, local entropy}% \gensee{local entropy weighting}{weighting, local entropy}% \item[Local Entropy]\itemend The entropy criteria prefers pixels inside a high-entropy neighborhood. In addition, \App{} allows the user to mitigate the problem of noisy images when using entropy weighting by setting a black threshold. \end{description} \noindent See \tableName~\ref{tab:default-weights} for the default weights of these criteria. For the concept of pixel weighting, and details on the different weighting functions, see \chapterName~\fullref{sec:weighting-functions}. Adjust how much importance is given to each criterion by setting the weight parameters on the command line. For example, if you set \begin{literal} --exposure-weight=1.0 --saturation-weight=0.5 \end{literal} \App{} will favor well-exposed pixels over highly-saturated pixels when blending the source images. The effect of these parameters on the final result will not always be clear in advance. The quality of the result is subject to your artistic interpretation. Playing with the weights may or may not give a more pleasing result. The authors encourage the users to experiment, perhaps using down-sized or cropped images for speed. \begin{geeknote} Down-sizing (also called ``down-sampling'') with a good interpolator reduces noise, which might not be desired to judge the image quality of the original-size image. Cropping can offer an alternative, though. \end{geeknote} \genidx{channel!alpha}% \App{} expects but does not require each input image to have an alpha channel. By setting the alpha values of pixels to zero, users can manually remove those pixels from consideration when blending. If an input image lacks an alpha channel, \App{} will issue a warning and continue assuming all pixels should contribute to the final output. Any alpha value other than zero is interpreted as ``this pixel should contribute to the final image''. The input images are processed in the order they appear on the command line. Multi\hyp{}layer images are processed from the first layer to the last before \App{} considers the next image on the command line. Consult \sectionName~\ref{sec:layer-selection} on how to change the images' order within multi\hyp{}layer image files. \genidx{SourceForge}% Find out more about \App{} on its \uref{\sourceforgenet}{SourceForge} \uref{\enblendsourceforgenet}{web page}. \genidx[\rangeendlocation]{overview} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/lorentzian.gp0000644000175000017500000000116612566032753014471 00000000000000default_optimum = 0.5 default_width = 0.2 fwhm_gaussian = 2.3548200450309493820231386529193992755 fwhm_lorentzian = 2.8284271247461900976033774484193961571 lorentzian(y, y_opt, width) = 1.0 / (1.0 + ((y - y_opt) / (width * fwhm_gaussian / fwhm_lorentzian))**2 / 2.0) set key bmargin center horizontal set samples 1023 set xlabel "$Y$" set xtics 0.2 set ylabel "$w$" set ytics 0.2 load DATA_DIR . "/colors.gp" plot [y = 0:1] \ lorentzian(y, default_optimum, 0.1) title "width = 0.1", \ lorentzian(y, default_optimum, 0.2) title "default width = 0.2", \ lorentzian(y, default_optimum, 0.4) title "width = 0.4" enblend-enfuse-4.2/doc/enfuse-local-contrast-weighting.tex0000644000175000017500000002737512667245423020705 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Local Contrast Weighting]{\label{sec:local-contrast-weighting}% \genidx{weighting!local contrast}% \gensee{local contrast}{weighting, local contrast}% Local Contrast Weighting} Local contrast weighting favors pixels inside a high contrast neighborhood. The notion of ``high contrast'' is defined either by two different criteria or by a blend of both: \begin{itemize} \item The standard deviation (\acronym{SDev}) of all the pixels in the local analysis window is large. See \sectionName~\fullref{sec:standard-deviation}. \item The Laplacian-of-Gaussian (\acronym{LoG}) has a large magnitude. See \sectionName~\fullref{sec:laplacian-of-gaussian}. \item If the \acronym{LoG} magnitude is below a given threshold, use \acronym{SDev} data, otherwise stick with \acronym{LoG}. See \sectionName~\fullref{sec:blend-sdev-and-log}. \end{itemize} \App{} converts every \acronym{RGB} image to grayscale before it determines its contrast. Option~\flexipageref{\option{--gray-projector}}{opt:gray-projector} controls the projector function. Depending on the subject, one of several grayscale projectors may yield the best black-and-white contrast for image fusion. In the following sections we describe each algorithm in detail. \subsection[Standard Deviation]{\label{sec:standard-deviation}% \genidx{weighting!contrast using standard deviation}% \gensee{contrast weighting using standard deviation}{weighting, contrast using standard deviation}% Standard Deviation} \genidx{window!local-analysis}% \gensee{local analysis window}{window, local-analysis}% The pixel under consideration~\textsf{C} sits exactly in the center of a square, the so-called local analysis window. It always has an uneven edge length. The user sets the size with option~\option{--contrast-window-size}. \figureName~\ref{fig:local-analysis-window} shows two windows with different sizes. \begin{figure} \begin{maxipage} \centering \includeimage{local-analysis-window} \end{maxipage} \caption[Local analysis window]{\label{fig:local-analysis-window}Examples of local analysis windows for the sizes~3 and~5. ``\textsf{C}'' marks the center where the pixel gets the weight. ``\textsf{N}'' denote neighboring pixels, which all contribute to the weight.} \end{figure} During the analysis, \App{} scans the local analysis window across all rows and all columns\footnote{In the current implementation a \code{floor(contrast-window-size / 2)}-wide border around the images remains unprocessed and gets a weight of zero.}\ of each of the input images to compute the contrast weight of every pixel. \begin{optionsummary} \item[--contrast-weight] \sectionName~\fullref{opt:contrast-weight} \item[--contrast-window-size] \sectionName~\fullref{opt:contrast-window-size} \item[--gray-projector] \sectionName~\fullref{opt:gray-projector} \item[--hard-mask] \sectionName~\fullref{opt:hard-mask} \end{optionsummary} \subsubsection[Statistical Moments]{\label{sec:statistical-moments}% \genidx{statistical moments}% Statistical Moments} \genidx{probability function}% \genidx{random variable}% We start with the probability function~$w$ of the random variable~$X$: \[ w: x \rightarrow p(\{\omega: X(\omega) = x\}). \] \noindent It associates a probability~$p$ with each of the $n$ different possible outcomes~$\omega$ of the random variable~$X$. \genidx{expectation value}% \genidx{moment!first}% \gensee{first moment}{moment, first}% Based on $w$, we define the expectation value or ``First Moment'' of the random variable~$X$: \[ \Ex X := \sum_{i = 1}^n x_i w(x_i). \] \genidx{variance}% \genidx{moment!second}% \gensee{second moment}{moment, second}% Using the definition of the expectation value, we define the variance, or ``Second Moment'' as \[ \Var X := \mbox{\Ex}\left( (X - \Ex X)^2 \right), \] \genidx{standard deviation}% \noindent and the standard deviation as \[ \sigma \, X := \sqrt{\Var X}. \] Obviously, the variance of $X$ is the expectation value of the squared deviation from the expectation value of $X$ itself. Note that the variance's dimension is $X$'s dimension squared; the standard deviation rectifies the dimension to make it comparable with $X$ itself again. \subsubsection[Estimators]{\label{sec:estimators}% \genidx{estimators}% Estimators} In \App{}, we assume that $X$ follows a uniform probability function~$w(x) = \mbox{const.}$ That is, all pixel values in the local analysis window are considered to be equally probable. Thus, the expectation value and the variance can be estimated from the pixel values like this \[ \mbox{\Ex } X := \frac{1}{n} \sum_{i = 1}^n x_i. \] \noindent In other words: the expectation value is the arithmetic mean of the lightness of all pixels in the local analysis window. Analogously, the variance becomes \[ \mbox{\Var } X := \frac{1}{n - 1} \, \mbox{\Ex}\left( (X - \mbox{\Ex } X)^2 \right). \] \subsection[Laplacian of Gaussian]{\label{sec:laplacian-of-gaussian}% \genidx{weighting!contrast using \propername{Laplacian}-of-\propername{Gaussian}}% \gensee{contrast weighting using \propername{Laplacian}-of-\propername{Gaussian}}% {weighting, contrast using \propername{Laplacian}-of-\propername{Gaussian}}% Laplacian of Gaussian} \genidx{Laplacian-of-Gaussian@\propername{Laplacian}-of-\propername{Gaussian}}% \gensee{Log@\acronym{LoG}}{\propername{Laplacian}-of-\propername{Gaussian}}% \begin{sloppypar} The \propername{Laplacian}-of-\propername{Gaussian} (\acronym{LoG}) is an operator to detect edges in an image. Sometimes the \acronym{LoG}-operator is also called \propername{Marr}-\propername{Hildreth} operator. A \propername{Laplacian}-of-\propername{Gaussian} operator, \uref{\hciiwrvigracommonfilters}{\code{vigra::laplacianOfGaussian}} is part of the package~\uref{\hciiwrvigra}{\acronym{VIGRA}} that \App{} is built upon and is used for edge detection if option~\option{--contrast-edge-scale} is non-zero and \option{--contrast-min-curvature} equal to or less than zero. \end{sloppypar} Let the \propername{Gaussian} function be \[ g(x, y) = \frac{1}{2 \pi \sigma^2} \, {\exp\left(-\frac{x^2 + y^2}{2 \sigma^2}\right)} \] \noindent The parameter~$\sigma$, the argument of option~\option{--contrast-edge-scale}, is the length scale on which edges are detected by $g(x, y)$. We apply the \propername{Laplacian} operator in \propername{Cartesian} coordinates \[ \bigtriangleup \equiv \nabla \cdot \nabla = \frac{\partial^2}{\partial x^2} + \frac{\partial^2}{\partial y^2} \] \noindent to $g(x, y)$, to arrive at a continuous representation of the two-dimensional filter kernel \begin{equation}\label{equ:laplacian-of-gaussian} k(x, y) = \frac{\xi^2 - 1}{\pi \sigma^4} \exp(-\xi^2), \end{equation} \noindent where we have used the dimensionless distance~$\xi$ from the origin \[ \xi^2 = \frac{x^2 + y^2}{2 \sigma^2}. \] \App{} uses a discrete approximation of $k$ in the convolution with the image. The operator is radially symmetric with respect to the origin, which is why we can easily plot it in \figureName~\ref{fig:laplacian-of-gaussian}, setting $R = \sqrt{x^2 + y^2}$. \begin{figure} \ifreferencemanual\begin{maxipage}\fi \centering \includeimage{laplacian-of-gaussian} \ifreferencemanual\end{maxipage}\fi \caption[\propername{Laplacian}-of-\propername{Gaussian}]{\label{fig:laplacian-of-gaussian}% Plot of the \propername{Laplacian}-of-\propername{Gaussian} function~$k(R)$, \equationabbr~\ref{equ:laplacian-of-gaussian}, for $\sigma = 0.5$, using $R = \sqrt{x^2 + y^2}$.} \end{figure} \noindent See also \uref{\hipriilog}{\acronym{HIPR2}: \propername{Laplacian}-of-\propername{Gaussian}}. Sometimes the \acronym{LoG} is plagued by noise in the input images. After all, it is a numerical approximation of the second derivative and deriving always ``roughens'' a function. The (normalized) mask files relentlessly disclose such problems. Use option~\option{--contrast-min-curvature} with a \emph{negative} argument~\metavar{CURVATURE} to suppress all edges with a curvature below $-\metavar{CURVATURE}$ (which is a positive value). Check the effects with the mask files and particularly the hard-mask files (\filename{\val{val:default-hard-mask-template}}) if using option~\option{--hard-mask}. To indicate the \metavar{CURVATURE} in relative terms, which is particularly comprehensible for humans, append a percent sign (\sample{\%}). Try minimum curvatures starting from $-0.5\%$ to $-3\%$. \begin{optionsummary} \item[--contrast-edge-scale] \sectionName~\fullref{opt:contrast-edge-scale} \item[--contrast-min-curvature] \sectionName~\fullref{opt:contrast-min-curvature} \item[--contrast-weight] \sectionName~\fullref{opt:contrast-weight} \item[--hard-mask] \sectionName~\fullref{opt:hard-mask} \end{optionsummary} \subsection[Blend \acronym{SDev} and \acronym{LoG}]% {\label{sec:blend-sdev-and-log}% \genidx{weighting!contrast using a blend of methods}% \gensee{contrast weighting using a blend of methods}{weighting, contrast using a blend of methods}% Blend Standard Deviation and \propername{Laplacian}\hyp{}of\hyp{}\propername{Gaussian}} \App{} can team the standard deviation computation and Laplacian of Gaussian to deliver the best of both methods. Use a \emph{positive} argument~\metavar{CURVATURE} with option~\option{--contrast-min-curvature} to combine both algorithms. In this mode of operation \App{} computes the \acronym{SDev}-weight and the \acronym{LoG}-weight, then uses the \acronym{LoG} to decide whether to go with that value or prefer the \acronym{SDev} data. If the \acronym{LoG} is greater than \metavar{CURVATURE} \App{} uses the weight delivered by the \acronym{LoG}, otherwise the \acronym{SDev}-weight is rescaled such that its maximum is equal to \metavar{CURVATURE}, and the scaled \acronym{SDev} is used as weight. This technique merges the two edge detection methods where they are best. The \acronym{LoG} excels with clear edges and cannot be fooled by strong but smooth gradients. However, it is bad at detecting faint edges and it is susceptible to noise. The \acronym{SDev} on the other hand shines with even the most marginal edges, and resists noise quite well. Its weakness is that is is easily deceived by strong and smooth gradients. Tuning \metavar{CURVATURE} the user can pick the best threshold for a given set of images. \begin{optionsummary} \item[--contrast-edge-scale] \sectionName~\fullref{opt:contrast-edge-scale} \item[--contrast-min-curvature] \sectionName~\fullref{opt:contrast-min-curvature} \item[--contrast-weight] \sectionName~\fullref{opt:contrast-weight} \item[--contrast-window-size] \sectionName~\fullref{opt:contrast-window-size} \item[--gray-projector] \sectionName~\fullref{opt:gray-projector} \item[--hard-mask] \sectionName~\fullref{opt:hard-mask} \end{optionsummary} \subsection[Scaling and Choice of Mode]{\label{sec:scaling-and-choice}% \genidx{scaling of parameters} \genidx{mode of operation (\acronym{SDev}, \acronym{LoG}, \dots)}% Scaling and Choice of Mode} Experience has shown that neither the parameters \metavar{EDGESCALE} and \metavar{CURVATURE} nor the mode of operation (\acronym{SDev}-only, \acronym{LoG}-only, or a blend of both) scales to different image sizes. In practice, this means that if you start with a set of reduced size images, say $2808 \times 1872$~pixels, carefully optimize \metavar{EDGESCALE}, \metavar{CURVATURE} and so on, and find \acronym{LoG}-only the best mode, and then switch to the original resolution of $5616 \times 3744$~pixels, multiplying (or dividing) the parameters by four and sticking to \acronym{LoG}-only might \emph{not} result in the best fused image. For best quality, perform the parameter optimization and the search for the most appropriate mode at the final resolution. %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enblend-visualization-image.tex0000644000175000017500000001014212676175546020070 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Visualization Image]{\label{sec:visualization-image}% \genidx{seam-line!visualization}% \gensee{visualization image}{seam-line, visualization}% \gensee{image!seam-line}{seam-line, visualization}% Visualization Image} The visualization image shows the symmetric difference of the pixels in the rectangular region where two images overlap. The larger the difference the lighter shade of gray it appears in the visualization image. \App{} paints the non-overlapping parts of the image pair -- these are the regions where \emph{no} blending occurs -- in \val{val:visualize-no-overlap-value-color}. Table~\ref{tab:visualization-colors} shows the meanings of all the colors that are used in seam-line visualization images. \begin{table} \begin{description} \item[\val{val:visualize-no-overlap-value-color} areas]\itemend Non-overlapping parts of image pair. \item[various shades of gray]\itemend Difference of the pixel values in the overlap region. \item[\val{val:visualize-state-space-color} dot]\itemend Location of an optimizer sample. \item[\val{val:visualize-first-vertex-value-color} dot]\itemend First sample of a line segment. \item[\val{val:visualize-next-vertex-value-color} dot]\itemend Any other but first sample of a line segment. \genidx{radius!Dijkstra@\propername{Dijkstra}}% \gensee{Dijkstra@\propername{Dijkstra} radius}{radius, \propername{Dijkstra}}% \item[\val{val:visualize-state-space-inside-color} dot]\itemend State space sample inside the \propername{Dijkstra} radius. \item[\val{val:visualize-state-space-unconverged-color} dot]\itemend Non-converged point. \item[\val{val:visualize-initial-path-color} line]\itemend Initial seam line as generated by the primary seam generator. \item[\val{val:visualize-short-path-value-color} line]\itemend Final seam line. \genidx{seam-line!endpoint!frozen}% \gensee{frozen seam-line endpoint}{seam-line, endpoint, frozen}% \item[\val{val:visualize-frozen-point} \val{val:mark-frozen-point}]\itemend Non-movable, or ``frozen'' endpoint of a seam-line segment that no optimizer is allowed to move around. \genidx{seam-line!endpoint!movable}% \gensee{movable seam-line endpoint}{seam-line, endpoint, movable}% \item[\val{val:visualize-movable-point} \val{val:mark-movable-point}]\itemend Movable endpoint of a seam-line segment, which seam-line optimizers can move. \end{description} \caption[Visualization colors an symbols]{% \label{tab:visualization-colors}% \genidx{seam-line!visualization image colors}% \gensee{colors!visualization image}{seam-line, visualization image colors}% \gensee{visualization image colors}{seam-line, visualization image colors}% Colors and symbols used in seam-line visualization images.} \end{table} \genidx{seam-line!visualization example}% \gensee{visualization image example}{seam-line, visualization example}% \figureName~\ref{fig:seam-line-visualization} shows an example of a seam-line visualization. It was produced with an \App{} run at all defaults plus passing options~\code{--fine-mask} and \code{--vi\shyp su\shyp al\shyp ize}. \begin{figure} \begin{maxipage} \centering \includeimage[width=1\linewidth]{seam-line-visualization} \end{maxipage} \caption[Seam-line visualization]{\label{fig:seam-line-visualization}% Seam-line visualization of a simple overlap. \ifhevea \relax\else The 853\classictimes238~pixel image has been rescaled to fit the width of the current page.\fi} \end{figure} The large \val{val:visualize-no-overlap-value-color} border is ``off-limits'' for \App, for the images do not overlap there. The dark wedge inside the \val{val:visualize-no-overlap-value-color} frame is where the images share a common region. The initial seam-line (\val{val:visualize-initial-path-color}) is almost straight with the exception of a single bend on the left side of the image and the final seam-line (\val{val:visualize-short-path-value-color}) meanders around it. %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/common-expert-options.tex0000644000175000017500000002566012676423754017000 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \subsection[Expert Options]{\label{sec:expert-options}% \genidx[\rangebeginlocation]{expert options}% \genidx{options!expert}% Expert Options}% Not a \commonpart! %%% IMPLEMENTATION NOTE: This file is included in both manuals, but %%% rendered differently by conditional inclusion; Enblend and Enfuse %%% have different sets of ``Expert Options''. Hence, the name prefix %%% `common-', but no `\commonpart' sign. \ifenblend Control inner workings of \App{} and in particular the interpretation of images. \fi \ifenfuse Control inner workings of \App{} and the reading\slash writing of weight masks. \fi \begin{codelist} \label{opt:fallback-profile}% \optidx[\defininglocation]{--fallback-profile}% \genidx{profile!fallback}% \gensee{fallback profile}{profile, fallback}% \genidx{luminance interval!trivial}% \genidx{RGB-cube@\acronym{RGB}-cube}% \item[--fallback-profile=\metavar{PROFILE-FILENAME}]\itemend Use the \acronym{ICC} profile in \metavar{PROFILE-FILENAME} instead of the default \acronym{sRGB}. This option only is effective if the input images come \emph{without} color profiles \emph{and} blending is not performed in the trivial luminance interval or \acronym{RGB}-cube. Compare option~\flexipageref{\option{--blend-colorspace}}{opt:blend-colorspace} and \chapterName~\fullref{sec:color-profiles} on color profiles. \label{opt:layer-selector}% \optidx[\defininglocation]{--layer-selector}% \genidx{layer selection}% \item[--layer-selector=\metavar{ALGORITHM}]\itemend Override the standard layer selector algorithm~\sample{\val{val:layer-selector}}. \App{} offers the following algorithms: \begin{codelist} \genidx{layer selection!all layers}% \item[all-layers]\itemend Select all layers in all images. \genidx{layer selection!first layer}% \item[first-layer]\itemend Select only first layer in each multi-layer image. For single-layer images this is the same as \sample{all-layers}. \genidx{layer selection!last layer} \item[last-layer]\itemend Select only last layer in each multi-layer image. For single-layer images this is the same as \sample{all-layers}. \genidx{layer selection!largest-layer} \item[largest-layer]\itemend Select largest layer in each multi-layer image, where the ``largeness'', this is the size is defined by the product of the layer width and its height. The channel width of the layer is ignored. For single-layer images this is the same as \sample{all-layers}. \genidx{layer selection!no layer} \item[no-layer]\itemend Do not select any layer in any image. This algorithm is useful to temporarily exclude some images in response files. \end{codelist} \ifenfuse \label{opt:load-masks}% \optidx[\defininglocation]{--load-masks}% \genidx{mask!loading}% \gensee{load mask}{mask, loading}% \item[\itempar{--load-masks~\textrm{(\oldstylefirst~form)} \\ --load-masks=\metavar{SOFT-MASK-TEMPLATE}~\textrm{(\oldstylesecond~form)} \\ --load-masks=\metavar{SOFT-MASK-TEMPLATE}:\feasiblebreak \metavar{HARD-MASK-TEMPLATE}~\textrm{(\oldstylethird~form)}}]\itemend Load masks from images instead of computing them. The masks must be grayscale images. All image formats understood by \App{} (see option~\flexipageref{\option{--show-image-formats}}{opt:show-image-formats}) are viable mask file formats, though those with floating-point pixels for example \acronym{TIFF} or \acronym{VIFF} are suited best. \genidx{mask!filename template}% \gensee{filename template}{mask, filename template}% \begin{sloppypar} \oldstylefirst~form: Load all soft-weight masks from files that were previously saved with option~\flexipageref{\option{--save-masks}}{opt:save-masks}. \metavar{HARD-MASK-TEMPLATE} is effective only when loading hard masks (see option~\flexipageref{\option{--hard-mask}}{opt:hard-mask}). The respective defaults are \mbox{\code{\val{val:default-soft-mask-template}}} and \mbox{\code{\val{val:default-hard-mask-template}}}. In the \oldstylesecond~form \metavar{SOFT\hyp{}MASK\hyp{}TEMPLATE} defines the names of the soft-mask files. In the \oldstylethird~form \metavar{HARD\hyp{}MASK\hyp{}TEMPLATE} additionally defines the names of the hard-mask files. See option~\flexipageref{\option{--save-masks}}{opt:save-masks} below for the description of mask templates. \end{sloppypar} Options~\option{--load-masks} and~\option{--save-masks} are mutually exclusive. \fi \label{opt:parameter}% \optidx[\defininglocation]{--parameter}% \item[--parameter=\metavar{KEY}\optional{=\metavar{VALUE}}\optional{:\dots}]\itemend Set a \metavar{KEY}-\metavar{VALUE} pair, where \metavar{VALUE} is optional. This option is cumulative. Separate multiple pairs with the usual numeric delimiters. This option has the negated form \optidx[\defininglocation]{--no-parameter}% \sample{--no-parameter}, which takes one or more \metavar{KEY}s and removes them from the list of defined parameters. The special key~\sample{*} deletes all parameters at once. Parameters allow the developers to change the internal workings of \App{} without the need to recompile or relink. \begin{sgquote} \Author{\genidx{Jackson, Daniel@\propername{Jackson, Daniel}}Daniel Jackson: }% \Quote{I just hope we won't regret giving them those gate addresses.} \Author{\genidx{O'Neill, Jack@\propername{O'Neill, Jack}}Jack O'Neill: }% \Quote{I don't think we will, first one being a black hole and all. They get progressively darker after that.} \end{sgquote} \ifenblend \label{opt:pre-assemble}% \optidx[\defininglocation]{--pre-assemble}% \shoptidx{-a}{--pre-assemble}% \genidx{preassemble}% \gensee{assemble}{preassemble}% \genidx{blending!sequential}% \gensee{sequential blending}{blending, sequential}% \item[\itempar{-a \\ --pre-assemble}]\itemend Pre-assemble non-overlapping images before each blending iteration. This overrides the default behavior which is to blend the images sequentially in the order given on the command line. \App{} will use fewer blending iterations, but it will do more work in each iteration. This option has the negated form \optidx[\defininglocation]{--no-pre-assemble}% \sample{--no-pre-assemble}, which restores the default. \fi %% -- Commented out for Stable Branch 4.2 %% \label{opt:prefer-gpu}% %% \optidx[\defininglocation]{--prefer-gpu}% %% \genidx{OpenCL}% %% \genidx{OpenCL!device}% %% \genidx{OpenCL!platform}% %% \item[--prefer-gpu=\optional{\metavar{PLATFORM}:}\metavar{DEVICE} %% \restrictednote{\acronym{OpenCL}-enabled versions only.}]\itemend %% Direct \App{} towards a particular \acronym{OpenCL} \metavar{DEVICE} on the first %% auto-detected \metavar{PLATFORM} or directly to the given \metavar{PLAT\shyp %% FORM}\slash\metavar{DE\shyp VICE} combination. Use the numbers of platform and %% device found either with %% %% \begin{terminal} %% \$ \app{} --verbose --version %% \end{terminal} %% or %% \begin{terminal} %% \$ \app{} --show-gpu-info %% \end{terminal} %% %% Note that this option only selects \acronym{GPU}-devices; it does not \emph{activate} any, use %% option~\flexipageref{\option{--gpu}}{opt:gpu} for that. %% %% When told to employ the \acronym{GPU} with \sample{--gpu}, by default \App{} uses the first %% device on the first auto-detected platform it finds via queries of the \acronym{OpenCL} %% subsystem, where neither the device, nor the platform may be the ones the user wants. Usually %% she will select the device with the highest performance, maximum possible number of %% work-items, and largest associated memory. \ifenblend \label{opt:x}% \optidx[\defininglocation]{-x}% \genidx{result!checkpoint}% \genidx{checkpoint results}% \item[-x] Checkpoint partial results to the output file after each blending step. \fi \ifenfuse \label{opt:save-masks}% \optidx[\defininglocation]{--save-masks}% \genidx{mask!save}% \gensee{save mask}{mask, save} \item[\itempar{--save-masks~\textrm{(\oldstylefirst~form)} \\ --save-masks=\metavar{SOFT-MASK-TEMPLATE}~\textrm{(\oldstylesecond~form)} \\ --save-masks=\metavar{SOFT-MASK-TEMPLATE}:\feasiblebreak \metavar{HARD-MASK-TEMPLATE}~\textrm{(\oldstylethird~form)}}]\itemend Save the generated weight masks to image files. \genidx{mask!filename template}% \gensee{filename template}{mask, filename template}% \begin{sloppypar} \oldstylefirst~form: Save all soft-weight masks in files. If option~\flexipageref{\option{--hard-mask}}{opt:hard-mask} is effective also save the hard masks. The defaults are \code{\val{val:default-soft-mask-template}} and \code{\val{val:default-hard-mask-template}}. In the \oldstylesecond~form \metavar{SOFT\hyp{}MASK\hyp{}TEMPLATE} defines the names of the soft-mask files. In the \oldstylethird~form \metavar{HARD\hyp{}MASK\hyp{}TEMPLATE} additionally defines the names of the hard-mask files. \end{sloppypar} \genidx{save mask!only}% \gensee{only save mask}{save mask only}% \App{} will stop after saving all masks unless option~\flexipageref{\option{--output}}{opt:output} is given, too. With both options given, this is, \sample{--save-masks} and \sample{--output}, \App{} saves all masks and then proceeds to fuse the output image. Both \metavar{SOFT\hyp{}MASK\hyp{}TEMPLATE} and \metavar{HARD\hyp{}MASK\hyp{}TEMPLATE} define templates that are expanded for each mask file. In a template a percent sign (\sample{\%}) introduces a variable part. All other characters are copied literally. Lowercase letters refer to the name of the respective input file, whereas uppercase ones refer to the name of the output file. \tableName~\fullref{tab:mask-template-characters} lists all variables. A fancy mask filename template could look like \begin{literal} \%D/mask-\%02n-\%f.tif \end{literal} It puts the mask files into the same directory as the output file (\sample{\%D}), generates a two-digit index (\sample{\%02n}) to keep the mask files nicely sorted, and decorates the mask filename with the name of the associated input file (\sample{\%f}) for easy recognition. \genidx{mask!floating-point \acronym{TIFF}}% \gensee{floating-point \acronym{TIFF} mask}{mask, floating-point \acronym{TIFF}}% The masks carry the totaled images' weights. They consist of single-channel, this is grayscale, floating-point data and thus preferably are saved in floating-point form. \App{} defaults to floating-point~\acronym{TIFF}. Options~\option{--load-masks} and~\option{--save-masks} are mutually exclusive. \fi \end{codelist} \ifenfuse \input{common-mask-template-characters} \fi \genidx[\rangeendlocation]{expert options} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/entropy-cutoff.gp0000644000175000017500000000124112566032753015262 00000000000000# Plot example of entropy-cutoff function Lower = 0.05 Upper = 0.9 Offset = 0 _Epsilon = 1.0 / 1024.0 Step(X) = X < 0 ? 0 : (X > _Epsilon ? 1 : 1/0) EntropyCutoffProper(Y, LowerCutoff, UpperCutoff) = \ Y <= LowerCutoff ? 0.0 : (Y >= UpperCutoff ? 1.0 : Y) EntropyCutoff(Y, LowerCutoff, UpperCutoff) = \ Step(Y - LowerCutoff) * Step(UpperCutoff - Y) * \ EntropyCutoffProper(Y, LowerCutoff, UpperCutoff) + \ Step(Y - UpperCutoff) set grid set key right bottom set samples 1023 set xlabel "$Y$" set xtics 0.2 set ylabel "$Y'$" set yrange [-0.1:1.1] set ytics 0.2 unset key load DATA_DIR . "/colors.gp" plot [Y = 0:1] EntropyCutoff(Y, Lower, Upper) enblend-enfuse-4.2/doc/enfuse-exposure-weighting-user-opencl.tex0000644000175000017500000003115412676175550022055 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \subsection[User-Defined \acronym{OpenCL} Functions]{\label{sec:user-defined-opencl-functions}% \genidx{weighting!exposure!user-defined!\acronym{OpenCL}}% User-Defined \acronym{OpenCL} Exposure Weighting Functions} See also \sectionName~\ref{sec:user-defined-dynlink-functions} on defining C++-weighting functions via dynamic linking. \subsubsection[Introduction]{\label{sec:user-defined-opencl-functions-introduction}% \genidx{weighting!exposure!\acronym{OpenCL} introduction}% Introduction} \genidx{\acronym{GPGPU}}% \genidx{\acronym{OpenCL}}% So what has \acronym{OpenCL} to do with user-defined exposure weighting functions? Every \acronym{OpenCL} system working on top of a \acronym{GPGPU} comes with a compiler and a linker specifically tailored for the \acronym{GPGPU}. Both tools are hidden in one or more libraries of the respective graphics card. \App{} reaps the benefits from these libraries already having been installed and uses the \acronym{OpenCL}-host interface to compile, link and execute \acronym{OpenCL}-programs on the \acronym{GPGPU}. In brief, if \appcmd{} has been built with \acronym{OpenCL} support, the system has all necessary libraries installed, the user can feed \acronym{OpenCL}-source code -- actually a C-dialect -- to \App{} without the need to install and maintain all the tools to compile \appcmd{} itself as in the previously described method of dynamic linking. The ability of \acronym{GPGPU}s to crunch humongous amounts of data is unimportant here. \smallskip \noindent\restrictednote{\acronym{OpenCL}-enabled versions only.} \optidx{--exposure-weight-function}% \optidx{--gpu}% For \App{} executables compiled with \acronym{OpenCL} support (see \sectionName~\fullref{sec:finding-out-details} on how to check this feature), \App{} can work with user-defined exposure weighting functions, passed with the long form of option~\option{--ex\shyp po\shyp sure\hyp weight\hyp function} after \acronym{GPU}-support has been requested with option~\option{--gpu}. \App{} compiles, links and evaluates the exposure-weight function identified by \metavar{SYMBOL} from \metavar{OPENCL-SOURCE}, where \metavar{OPENCL-SOURCE} has extension~\filename{.cl}: \begin{literal} --gpu --exposure-weight-function=\metavar{OPENCL-SOURCE}:\feasiblebreak \metavar{SYMBOL}\optional{:\feasiblebreak \metavar{AR\shyp GU\shyp MENT}\optional{:\dots}} \end{literal} If \metavar{SYMBOL} is not found in \metavar{OPENCL-SOURCE} or does not define a suitable function, \App{} aborts with an extensive error message. In \exampleName~\ref{ex:opencl-userweight-error} we supply a wrong \metavar{SYMBOL} called \sample{foobar}, whereas \filename{variable\_power.cl} -- one of the supplied examples -- actually defines \sample{weight}. \begin{exemplar} \begin{maxipage} \begin{terminal} \$ enfuse --gpu --exposure-weight-function=variable\_power.cl:foobar image-[0-9].tif \\ enfuse: info: chose OpenCL platform \#2, NVIDIA Corporation, NVIDIA CUDA, device \#1 \\ enfuse: invalid binary \\ enfuse: note: build status \\ enfuse: note:~~~~~error (status-code = -2) \\ enfuse: note: build options \\ enfuse: note: ~~~~-cl-nv-verbose \bslash \\ ~~~~~~~~~~~~~~~~~~-cl-single-precision-constant \bslash \\ ~~~~~~~~~~~~~~~~~~-I/usr/local/share/enblend/kernels \bslash \\ ~~~~~~~~~~~~~~~~~~-I/usr/share/enblend/kernels \bslash \\ ~~~~~~~~~~~~~~~~~~-DENFUSE\_FWHM\_GAUSSIAN=2.354820f \bslash \\ ~~~~~~~~~~~~~~~~~~-DENFUSE\_OPTIMUM\_Y=0.5f \bslash \\ ~~~~~~~~~~~~~~~~~~-DENFUSE\_USER\_WEIGHT\_FUNCTION=foobar \bslash \\ ~~~~~~~~~~~~~~~~~~-DENFUSE\_WIDTH=0.2f \\ enfuse: note: build log \\ enfuse: note:~~~~~ptxas fatal: Unresolved extern function 'foobar' \end{terminal} \end{maxipage} \caption[\acronym{OpenCL} user-weight error]% {\label{ex:opencl-userweight-error}% Error output of \App{} for an invalid (here: unknown) user-defined \acronym{OpenCL} exposure-weight function. The actual error output error differs for different graphics-card manufacturers.} \end{exemplar} \subsubsection[\acronym{OpenCL} Coding Guidelines]{\label{sec:opencl-coding-guidelines}% \genidx{coding guidelines!\acronym{OpenCL}}% \acronym{OpenCL} Coding Guidelines} \begin{enumerate} \item Define a weight-function with following signature \begin{cxxlisting} float weight(float y); \end{cxxlisting} in a text file. It takes a luminance in the normalized interval~$(0, 1)$ and returns the weight. This function name will become \metavar{SYMBOL} at the \App{} command line. \item Pass filename~\metavar{OPENCL-SOURCE} (with extension~\filename{.cl}) of the text file and the function name~\metavar{SYMBOL} to \App{} as shown above. \genidx{environment variable!ENBLEND\_OPENCL\_PATH@\envvar{ENBLEND\_OPENCL\_PATH}}% \item \metavar{OPENCL-SOURCE} can include (\code{\#include "\dots"}) other files. The include path is \envvar{ENBLEND\_OPENCL\_PATH}. Note that the environment variable starts with ``ENBLEND'', not ``ENFUSE''. \item\sloppypar All \metavar{ARGUMENT}s are converted to preprocessor symbols (\code{\#define \dots}) and passed to the \acronym{OpenCL}-compiler when it processes \metavar{OPENCL-SOURCE}. For example, adding an \metavar{ARGUMENT} like \sample{EXPONENT=1.25} will add \sample{-DEXPONENT=1.25} to the compiler options, which is equivalent to saying \begin{cxxlisting} #define EXPONENT 1.25 \end{cxxlisting} at the top of \metavar{OPENCL-SOURCE}. To make the \metavar{ARGUMENT}s optional at the \app{} command line use the \begin{cxxlisting} #ifndef ARGUMENT #define ARGUMENT ... #endif \end{cxxlisting} idiom in the source code and supply a reasonable default. \genidx{OpenCL helpers@\acronym{OpenCL} helpers}% \item \App{} supplies a set of preprocessor symbols and functions to each user-defined function. They simplify writing weight functions. Each one starts with \sample{ENFUSE\_} (preprocessor symbols) or \sample{enfuse\_} (functions) to avoid name collisions or shadowing. \begin{codelist} \genidx{OpenCL helpers@\acronym{OpenCL} helpers!ENFUSE-OPTIMUM-Y@\code{ENFUSE\_OPTIMUM\_Y}}% \gensee{ENFUSE-OPTIMUM-Y@\code{ENFUSE\_OPTIMUM\_Y}}{\acronym{OpenCL} helpers, \code{ENFUSE\_OPTIMUM\_Y}}% \genidx{exposure!optimum}% \optidx{--exposure-optimum}% \item[ENFUSE\_OPTIMUM\_Y]\itemend The \code{float}-value of the optimum luminance in the normalized luminance interval. The user sets this value with option~\option{--exposure-optimum} (default:~\val{val:default-exposure-optimum}, see \sectionName~\fullref{opt:exposure-optimum}). \genidx{OpenCL helpers@\acronym{OpenCL} helpers!ENFUSE-WIDTH@\code{ENFUSE\_WIDTH}}% \gensee{ENFUSE-WIDTH@\code{ENFUSE\_WIDTH}}{\acronym{OpenCL} helpers, \code{ENFUSE\_WIDTH}}% \genidx{exposure!weight}% \optidx{--exposure-width}% \item[ENFUSE\_WIDTH]\itemend The characteristic width of the weight function as \code{float}. Set this value at the command line with option~\option{--exposure-width} (default:~\val{val:default-exposure-width}, see \sectionName~\fullref{opt:exposure-width}). \genidx{OpenCL helpers@\acronym{OpenCL} helpers!ENFUSE-FWHM-GAUSSIAN@\code{ENFUSE\_FWHM\_GAUSSIAN}}% \gensee{ENFUSE-FWHM-GAUSSIAN@\code{ENFUSE\_FWHM\_GAUSSIAN}}% {\acronym{OpenCL} helpers, \code{ENFUSE\_FWHM\_GAUSSIAN}}% \item[ENFUSE\_FWHM\_GAUSSIAN]\itemend Shorthand for the width of \App's first ever weight function, \sample{gauss} (see \sectionName~\ref{sec:built-in-functions}). Use the value to rescale the width of the newly written user function to make it behave like a predefined one with respect to the full-width at half of the maximum. The actual value, $2 \sqrt{2 \log(2)}$, is approximately 2.35482. \genidx{OpenCL helpers@\acronym{OpenCL} helpers!enfuse-normalized-luminance@\code{enfuse\_normalized\_luminance}}% \gensee{enfuse-normalized-luminance@\code{enfuse\_normalized\_luminance}}% {\acronym{OpenCL} helpers, \code{enfuse\_normalized\_luminance}}% \item[enfuse\_normalized\_luminance]\itemend Helper function which implements \flexipageref{\equationabbr~\ref{equ:linear-luminance-transform}}{equ:linear-luminance-transform}. \begin{cxxlisting} float enfuse_normalized_luminance(float y) { return (y - ENFUSE_OPTIMUM_Y) / ENFUSE_WIDTH; } \end{cxxlisting} \end{codelist} \end{enumerate} \begin{geeknote} The weight function's signature being so simple and weight functions usually also being simple none of the language-specific features like, for example, \code{local}-\slash\code{global} address spaces, synchronization nor vector-data types are required to write useful weight functions. In particular, \App's \acronym{OpenCL} exposure weight functions are \emph{not} \code{kernel} functions. \end{geeknote} Examples~\ref{ex:opencl-generalized-gaussian-weight} and \ref{ex:variable-opencl-exposure-weight-function} show how weight functions can be constructed using \acronym{OpenCL}. \exampleName~\ref{ex:opencl-generalized-gaussian-weight} implements \[ w(z) = \exp\left(-|z|^{\mathtt{EXPONENT}}\right), \] where $\code{EXPONENT} = 2$ obviously duplicates the pre-defined \propername{Gaussian} weight, \flexipageref{\equationabbr~\ref{equ:weight:gauss}}{equ:weight:gauss}. \begin{exemplar} \begin{cxxlisting} #ifndef EXPONENT #define EXPONENT 2.0f #endif float weight(float y) { return exp(-pow(fabs(enfuse_normalized_luminance(y)), EXPONENT)); } \end{cxxlisting} \caption[Generalized \propername{Gauss} weight function]% {\label{ex:opencl-generalized-gaussian-weight}% Generalized \propername{Gauss} weight function written in \acronym{OpenCL}. Note the definition of the default parameter~\code{EXPONENT}.} \end{exemplar} Assuming \exampleName~\ref{ex:opencl-generalized-gaussian-weight} is stored in \filename{generalized\_gaussian.cl} and reachable via an element in \envvar{ENBLEND\_OPENCL\_PATH} it can be used as \begin{literal} \app{} --gpu --exposure-weight-function=\feasiblebreak generalized\_gaussian.cl:\feasiblebreak weight \dots \end{literal} or \begin{literal} \app{} --gpu --exposure-weight-function=\feasiblebreak generalized\_gaussian.cl:\feasiblebreak weight:\feasiblebreak EXPONENT=1.5 \dots \end{literal} \exampleName~\ref{ex:variable-opencl-exposure-weight-function} implements the same variable weight as \exampleName~\ref{ex:variable-dynamic-exposure-weight-function} just without the parameter checks: \[ w(z) = \left\{ \begin{array}{cl} 1 - |z|^{\mathtt{EXPONENT}} & \mbox{if } |z| \leq 1 \\ 0 & \mbox{otherwise.} \end{array} \right. \] \begin{exemplar} \begin{cxxlisting} #ifndef M_LN2 #define M_LN2 0.69314718f #endif #ifndef EXPONENT #define EXPONENT 2.0f #endif float normalized_luminance(float y) { const float fwhm = 2.0f / exp(M_LN2 / EXPONENT); return enfuse_normalized_luminance(y) * (fwhm / ENFUSE_FWHM_GAUSSIAN); } float variable_power_weight(float y) { return max(1.0f - pow(fabs(normalized_luminance(y)), EXPONENT), 0.0f); } \end{cxxlisting} \caption[\acronym{OpenCL} exposure weight function with an extra argument]% {\label{ex:variable-opencl-exposure-weight-function}% \acronym{OpenCL} exposure weight function with extra argument~\code{EXPONENT} that defaults to 2. Also compare with \exampleName~\ref{ex:variable-dynamic-exposure-weight-function} for the implementation of almost the same functionality using dynamic linking.} \end{exemplar} Say \exampleName~\ref{ex:variable-opencl-exposure-weight-function} is stored in \filename{variable\_power.cl} and reachable via an element in \envvar{ENBLEND\_OPENCL\_PATH} then is can be used as \begin{literal} \app{} --gpu \bslash \\ ~~~~--exposure-weight-function=\bslash \\ ~~~~variable\_power.cl:variable\_power\_weight \dots \end{literal} or \begin{literal} \app{} --gpu \bslash \\ ~~~~--exposure-weight-function=\bslash \\ ~~~~variable\_power.cl:variable\_power\_weight:EXPONENT=3 \dots \end{literal} \optidx{--exposure-weight}% \optidx{--exposure-optimum}% \optidx{--exposure-width}% Options~\option{--exposure-weight}, \option{--exposure-optimum} as well as \option{--ex\shyp po\shyp sure\hyp width} work as expected for user-defined functions, too. \begin{sgquote} \Quote{All debts have now been paid.} -- \Author{\genidx{Linea@\propername{Linea}}% \gensee{Ke'ra@\propername{Ke'ra}}{\propername{Linea}}% \propername{Linea}, Destroyer of Worlds (\propername{Ke'ra})} \end{sgquote} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/htmlstyle.tex0000644000175000017500000001415112676175560014527 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. %% Open ``Color Schemer Online'' %% http://www.colorschemer.com/online.html %% enter '66FF33' in the field `#' and click `Set HEX'. The first column ``Color Suggestions''. %% The color names are our own; they are neither related to X11 or dvi2ps color names. %% %% Suggestions Color Name CSS Usage Print Replacement %% =========== ============= ============= ================= %% #66ff33 limegreen chapter %% #33ff66 grassgreen section %% #33ffcc seagreen subsection %% #33ccff skyblue subsubsection %% #3366ff navyblue %% #6633ff violetblue %% #cc33ff purple %% #ff33cc rhodamine fix-me lightgray %% #ff3366 orangered %% #ff6633 brickred %% #ffcc33 dandelion restrictednote %% #ccff33 springgreen geeknote lightlightgray %% #3df500 green terminal %% #2eb800 forestgreen %% #b800f5 orchid %% #8a00b8 fuchsia %% %% Supplements %% ----------- ------------- ------------- ----------------- %% #cccccc gray literal %% Physical Color Definitions \definecolor{limegreen}{rgb}{0.4, 1, 0.2} % #66ff33 \definecolor{grassgreen}{rgb}{0.2, 1, 0.4} % #33ff66 \definecolor{seagreen}{rgb}{0.2, 1, 0.8} % #33ffcc \definecolor{skyblue}{rgb}{0.2, 0.8, 1} % #33ccff \definecolor{navyblue}{rgb}{0.2, 0.4, 1} % #3366ff \definecolor{violetblue}{rgb}{0.4, 0.2, 1} % #6633ff \definecolor{purple}{rgb}{0.8, 0.2, 1} % #cc33ff \definecolor{rhodamine}{rgb}{1, 0.2, 0.8} % #ff33cc \definecolor{orangered}{rgb}{1, 0.2, 0.4} % #ff3366 \definecolor{brickred}{rgb}{1, 0.4, 0.2} % #ff6633 \definecolor{dandelion}{rgb}{1, 0.8, 0.2} % #ffcc33 \definecolor{springgreen}{rgb}{0.8, 1, 0.2} % #ccff33 \definecolor{green}{rgb}{0.24, 0.96, 0} % #3df500 \definecolor{forestgreen}{rgb}{0.18, 0.72, 0} % #2eb800 \definecolor{orchid}{rgb}{0.72, 0, 0.96} % #b800f5 \definecolor{fuchsia}{rgb}{0.54, 0, 0.72} % #8a00b8 \definecolor{black}{rgb}{0, 0, 0} \definecolor{gray}{rgb}{0.8, 0.8, 0.8} \definecolor{lightgray}{rgb}{0.9, 0.9, 0.9} \definecolor{lightlightgray}{rgb}{0.95, 0.95, 0.95} \definecolor{white}{rgb}{1, 1, 1} %% Logical Color Definitions \newcommand*{\bodybackgroundcolor}{white} \newcommand*{\bodyforegroundcolor}{black} \newcommand*{\chapterbackgroundcolor}{limegreen} \newcommand*{\fixmebackgroundcolor}{\ifhevea rhodamine\else lightgray\fi} \newcommand*{\geeknotebackgroundcolor}{\ifhevea springgreen\else lightlightgray\fi} \newcommand*{\literalbackgroundcolor}{gray} \newcommand*{\restrictedmaterialbordercolor}{dandelion} \newcommand*{\sectionbackgroundcolor}{grassgreen} \newcommand*{\subsectionbackgroundcolor}{seagreen} \newcommand*{\subsubsectionbackgroundcolor}{skyblue} \newcommand*{\terminalbackgroundcolor}{black} \newcommand*{\terminalbordercolor}{gray} \newcommand*{\terminalcolor}{green} \newcommand*{\titlebackgroundcolor}{skyblue} \newcommand*{\titleforegroundcolor}{black} %% Font Family Definitions %% * Helpful page: http://www.w3schools.com/css/css_font.asp %% * Note: We use sans-serif fonts for \seriffontfamily. %% A possible serif-set for \seriffontfamily is Georgia, serif. \newcommand*{\seriffontfamily}{Verdana, Geneva, sans-serif} \newcommand*{\sansfontfamily}{Verdana, Geneva, sans-serif} \newcommand*{\fixedfontfamily}{"Andale Mono", Courier, monospace} \newstyle{.adalisting}% {% font-family: \fixedfontfamily; white-space: pre; } \newstyle{body}% {% background: \@getcolor{\bodybackgroundcolor}; color: \@getcolor{\bodyforegroundcolor}; font-family: \seriffontfamily; margin-left: 15\%; margin-right: 15\%; } \newstyle{.chapter}% {% background: \@getcolor{\chapterbackgroundcolor}; margin-left: -10\%; margin-right: -10\%; padding: 0.75em; } \newstyle{.clearfix}% {% overflow: auto; } \newstyle{.cxxlisting}% {% font-family: \fixedfontfamily; white-space: pre; } \newstyle{.dt-list}% {% font-weight: bold; } \newstyle{.dt-thefootnotes}% {% font-size: smaller; } \newstyle{.footnotetext}% {% font-size: smaller; } \newstyle{.literal}% {% background: \@getcolor{\literalbackgroundcolor}; padding: 0.5em; } \newstyle{.marginpar}% {% border-color: lightgray; border-style: none; border-width: medium; font-size: small; } \newstyle{.marginparright}% {% border-left-style: solid; padding-left: .667em; } \newstyle{.marginparleft}% {% border-right-style: solid; padding-right: .667em; } \newstyle{.maxipage}% {% border-bottom: thin; border-top: thin; margin-left: -10\%; margin-right: -10\%; } \newstyle{.restrictedmaterial}% {% border-color: \@getcolor{\restrictedmaterialbordercolor}; border-style: solid; border-width: thick; padding: 0.5em; } \newstyle{.geeknote}% {% background: \@getcolor{\geeknotebackgroundcolor}; padding-bottom: 0.25em; padding-left: 0.333em; padding-right: 0.333em; padding-top: 0.25em; } %%\newstyle{.quote}% %%{% %% font-style: oblique; %%} \newstyle{.section}% {% background: \@getcolor{\sectionbackgroundcolor}; margin-left: -10\%; margin-right: -10\%; padding: 0.75em; } \newstyle{.subsection}% {% background: \@getcolor{\subsectionbackgroundcolor}; padding: 0.5em; } \newstyle{.subsubsection}% {% background: \@getcolor{\subsubsectionbackgroundcolor}; padding: 0.5em; } \newstyle{.terminal}% {% background: \@getcolor{\terminalbackgroundcolor}; border-color: \@getcolor{\terminalbordercolor}; border-style: solid; border-width: thick; color: \@getcolor{\terminalcolor}; font-family: \fixedfontfamily; padding: 0.25em; } \newstyle{.title} { font-family: \sansfontfamily; } \newstyle{.titlemain}% {% background: \@getcolor{\titlebackgroundcolor}; color: \@getcolor{\titleforegroundcolor}; font-weight: bolder; padding: 1em; } \newstyle{.titlerest}% {% font-weight: lighter; padding: 0.5em; } %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/TexAux.pm0000644000175000017500000000175612665527065013542 00000000000000# name: TexAux.pm # synopsis: Helper functions for TeX/LaTeX processing # author: Dr. Christoph L. Spiel # perl version: 5.20.2 # This file is part of Enblend. # Licence details can be found in the file COPYING. package TexAux; use strict; use warnings; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(escape lift default_name); sub escape { my $string = shift; $string =~ s#([\$&%_^{}])#\\$1#g; return $string; } sub lift { my $string = shift; if ($string =~ m#^https?:#) { $string = "\\url{$string}"; } else { $string =~ s#:#:\\feasiblebreak #g; $string =~ s#(? '\\definedbypreprocessor', FIND_MACRO_NAME => '\\hashfind', INSERT_MACRO_NAME => '\\hashinsert', KEY_PREFIX => 'val:', UNDEF_MACRO_VALUE => '\\undefinedbypreprocessor'); sub default_name { my $id = shift; return $defaults{$id}; } 1; enblend-enfuse-4.2/doc/enblend-image-requirements.tex0000644000175000017500000000340212667236617017710 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Image Requirements]{\label{sec:image-requirements}% \genidx{image requirements}% \genidx{requirements!image}% Input Image Requirements} All input images for \App{} must comply with the following requirements. \begin{itemize} \item Parts of the images overlap. \item Each image has an alpha channel also called ``mask''. \item The images agree on their number of channels: \begin{itemize} \item one plus alpha or \item three plus alpha. \end{itemize} This is, either all images are black-and-white (one channel and alpha channel) or all are \acronym{RGB}-color images (three channels and alpha channel). \item The images agree on their number of bits-per-channel, i.e., their ``depth'': \begin{itemize} \item \code{uint8}, \item \code{uint16}, \item \code{float}, \item etc. \end{itemize} See option~\flexipageref{\option{--depth}}{opt:depth} for an explanation of different output depths. \item \App{} understands the images' filename extensions as well as their file formats. You can check the supported extensions and formats by calling \App{} with option~\flexipageref*{\option{--show-image-formats}}{opt:show-image-formats}. \end{itemize} Moreover, there are some good practices, which are not enforced by the application, but almost certainly deliver superior results. \begin{itemize} \item Either all files lack an \acronym{ICC} profile, or all images are supplied with the \emph{same} \acronym{ICC} profile. \item If the images' meta-data contains resolution information (``\acronym{DPI}''), it is the same for all pictures. \end{itemize} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enblend-title.tex0000644000175000017500000000255212676175540015230 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \begin{titlepage} \renewcommand{\thefootnote}{\fnsymbol{footnote}} \author{Andrew~Mihal\footnote{Original author} \and Christoph~Spiel} \title{Combining Multiple Images\\ with\\ Enblend \val*{val:VERSION}} \date{\val*{val:UPDATED}} \maketitle \end{titlepage} \pagenumbering{roman} \vspace*{\fill} \ifhevea \relax \else \begin{center}\strong{Abstract}\end{center} \fi \label{sec:abstract}\noindent This manual is for \App{} version~\val{val:VERSION}, a tool for compositing images in such a way that the seam between the images is invisible, or at least very difficult to see. \vspace*{\fill} \begin{flushleft} Copyright \copyright{} 2004--2009 \propername{Andrew Mihal}. \\ Copyright \copyright{} 2009--2016 \propername{Christoph Spiel}. \end{flushleft} \begin{quotation} \noindent Permission is granted to copy, distribute and/or modify this document under the terms of the \acronym{GNU} Free Documentation License, Version~1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. A copy of the license is included in the section entitled ``\acronym{GNU} Free Documentation License''. \end{quotation} \cleardoublepage{} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/exposure-cutoff.gp0000644000175000017500000000135012566032753015435 00000000000000# Plot example of exposure-cutoff function Lower = 0.05 Upper = 0.97 Mu = 0.5 Sigma = 0.2 _Epsilon = 1.0 / 1024.0 Step(X) = X < 0 ? 0 : (X > _Epsilon ? 1 : 1/0) Gaussian(Y, Mu, Sigma) = exp(-0.5 * ((Y - Mu) / Sigma)**2) ExposureCutoffProper(Y, LowerCutoff, UpperCutoff) = \ Y <= LowerCutoff ? 0 : (Y >= UpperCutoff ? 0 : Gaussian(Y, Mu, Sigma)) ExposureCutoff(Y, LowerCutoff, UpperCutoff) = \ Step(Y - LowerCutoff) * \ Step(UpperCutoff - Y) * \ ExposureCutoffProper(Y, LowerCutoff, UpperCutoff) set grid set key right bottom set samples 1023 set xlabel "$Y$" set xtics 0.2 set ylabel "$w_Y$" set yrange [-0.1:1.1] set ytics 0.2 unset key load DATA_DIR . "/colors.gp" plot [Y = 0:1] ExposureCutoff(Y, Lower, Upper) enblend-enfuse-4.2/doc/enfuse-options.tex0000644000175000017500000000215012667236617015455 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Command-Line Options]{\label{sec:options}% \genidx[\rangebeginlocation]{options}% Command-Line Options} In this section we group the options as the command-line help \begin{terminal} \$ \app{} --help \end{terminal} does and sort them alphabetically within their groups. For an alphabetic list of \emph{all} options consult the \flexipageref{Option Index}{sec:option-index}. \appcmd{} accepts arguments to any option in uppercase as well as in lowercase letters. For example, \sample{deflate}, \sample{Deflate} and \sample{DEFLATE} as arguments to the \option{--compression}~option described below all instruct \appcmd{} to use the \propername{Deflate} compression scheme. This manual denotes all arguments in lowercase for consistency. \input{common-common-options} \input{common-advanced-options} \input{enfuse-fusion-options} \input{common-expert-options} \input{enfuse-expert-fusion-options} \input{common-information-options} \genidx[\rangeendlocation]{options} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/smooth-edge.data0000644000175000017500000000015612541464343015015 000000000000000 62 125 187 250 1 63 126 188 251 2 65 127 190 252 3 66 128 191 253 5 67 130 192 255 enblend-enfuse-4.2/doc/photographic-workflow.dot0000644000175000017500000000232312562317012017005 00000000000000digraph PhotographicWorkflow { graph [uml_activity_graph] node [uml_activity] _start [uml_start] take [label = "Take Images"] if_raw_branch [uml_branch] convert [label = "Convert Images"] if_raw_merge [uml_merge] align [label = "Align Images"] combine [label = "Combine Images"] postprocess [label = "Postprocess"] _finish [uml_finish] node [uml_note] convert_note [label = "DCRaw, UFRaw, etc."] align_note [label = "Hugin, PanoTools"] combine_note [label = "Enblend, Enfuse"] postprocess_note [label = "The Gimp et al."] {rank = same; convert; convert_note} {rank = same; align; align_note} {rank = same; combine; combine_note} {rank = same; postprocess; postprocess_note} edge [uml_edge] _start -> take take -> if_raw_branch if_raw_branch -> convert [taillabel = " [raw] ", weight = 10] if_raw_branch -> if_raw_merge [taillabel = " [else] "] convert -> if_raw_merge [weight = 10] if_raw_merge -> align align -> combine combine -> postprocess postprocess -> _finish edge [uml_note_edge] convert -> convert_note align -> align_note combine -> combine_note postprocess -> postprocess_note } enblend-enfuse-4.2/doc/common-known-limitations.tex0000644000175000017500000000511512676175546017462 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Known Limitations]{\label{sec:known-limitations}% \genidx[\rangebeginlocation]{known limitations}% Known Limitations} \App{} has its limitations. Some of them are inherent to the programs proper others are ``imported'' by using libraries as for example \uref{\hciiwrvigra}{\acronym{VIGRA}}. Here are some of the known ones. \begin{itemize} \item The \genidx{BigTIFF@\acronym{BigTIFF}}\acronym{BigTIFF} image format is not supported. \item Total size of \emph{any} -- even intermediate -- image is limited to $2^{31}$~pixels, this is two giga-pixels. \ifenblend \genidx{blending!sequential}% \gensee{sequential blending}{blending, sequential}% \item Each ``next'' image must overlap with the result of the blending of all previous images. In special occasions option~\sample{--pre-assemble} can circumvent this sequential-blending restriction. \item No pair of images must overlap too much. In particular, no two images must be identical. \begin{geeknote} The overlap is exclusively defined by the masks of the overlapping images. This is exactly what the input masks are built for. Let $A$ be the number of pixels that overlap in both masks. We use $A$ as a measure of the overlap area -- something 2\hyp dimensional; technically it is a pixel count. Construct the smallest circumscribed, par-axial rectangle of the overlap area. The rectangle has a circumference \[ U = 2 (a + b), \] which is of course 1-dimensional. Internally $U$ again is a number of pixels just as $A$. The threshold when we consider a pair of images sufficiently different is when $A$ is larger than \val{val:overlap-check-threshold}~times the number of pixels on the circumference~$U$ \[ A > \val{val:overlap-check-threshold} \times U. \] Avoiding the term ``fractal dimension'', we have constructed a simple measure of how 2\hyp dimensional the overlap area is. This way we steer clear of feeding later processing stages with nearly 1\hyp dimensional overlap regions, something that wreaks havoc on them. \end{geeknote} \optidx{--wrap} \item Option~\sample{--wrap=both} performs blending in $\symmgroup{E}(1) \times \symmgroup{E}(1)$, which is only \emph{locally} isomorphic to $\symmgroup{S}(2)$. This will cause artifacts that do not appear in $\symmgroup{S}(2)$. \App{} cannot blend within $\symmgroup{S}(2)$. \fi%enblend \end{itemize} \genidx[\rangeendlocation]{known limitations} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/common-option-delimiters.tex0000644000175000017500000000416512676175540017441 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Option Delimiters\commonpart]{\label{sec:option-delimiters}% \genidx{options!delimiters}% \gensee{option delimiters}{options, delimiters}% \gensea{delimiters}{options, delimiters}% Option Delimiters\commonpart} \App{} and \OtherApp{} allow the arguments supplied to the programs' options to be separated by different separators. The online documentation and this manual, however, exclusively use the colon~\sample{:} in every syntax definition and in all examples. \subsection[Numeric Arguments]{\label{sec:option-delimiters-numeric-arguments}% \genidx{options!delimiters!numeric arguments}% Numeric Arguments} Valid delimiters are the semicolon~\sample{;}, the colon~\sample{:}, and the slash~\sample{/}. All delimiters may be mixed within any option that takes numeric arguments. Examples using some \application{Enfuse} options: \begin{codelist} \item[--contrast-edge-scale=0.667:6.67:3.5]\itemend Separate all arguments with colons. \item[--contrast-edge-scale=0.667;6.67;3.5]\itemend Use semi-colons. \item[--contrast-edge-scale=0.667;6.67/3.5]\itemend Mix semicolon and slash in weird ways. \item[--entropy-cutoff=3\%/99\%]\itemend All delimiters also work in conjunction with percentages. \item[--gray-projector=channel-mixer:3/6/1]\itemend Separate arguments with a colon and two slashes. \item[--gray-projector=channel-mixer/30;60:10]\itemend Go wild and \application{Enfuse} will understand. \end{codelist} \subsection[Filename Arguments]{\label{sec:option-delimiters-filename-arguments}% \genidx{options!delimiters!filename arguments}% Filename Arguments} Here, the accepted delimiters are comma~\sample{,}, semicolon~\sample{;}, and colon~\sample{:}. Again, all delimiters may be mixed within any option that has filename arguments. Examples: \begin{codelist} \item[--save-masks=soft-mask-\%03i.tif:hard-mask-03\%i.tif]\itemend Separate all arguments with colons. \item[--save-masks=\%d/soft-\%n.tif,\%d/hard-\%n.tif]\itemend Use a comma. \end{codelist} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/common-advanced-options.tex0000644000175000017500000003147712676175561017241 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \subsection[Advanced Options\commonpart]{\label{sec:advanced-options}% \genidx[\rangebeginlocation]{advanced options}% \genidx{options!advanced}% Advanced Options\commonpart} Advanced options control e.g.\ the channel depth, color model, and the cropping of the output image. \begin{codelist} \label{opt:blend-colorspace}% \optidx[\defininglocation]{--blend-colorspace}% \genidx{colorspace!blend}% \gensee{blend colorspace}{colorspace, blend}% \genidx{color appearance model}% \item[--blend-colorspace=\metavar{COLORSPACE}]\itemend Force blending in selected \metavar{COLORSPACE}. Given well matched images this option should not change the output image much. However, if \App{} must blend vastly different colors (as e.g.\ anti-colors) the resulting image heavily depends on the \metavar{COLORSPACE}. Usually, \App{} chooses defaults depending on the input images: \begin{itemize} \genidx{profile!ICC@\acronym{ICC}}% \gensee{ICC@\acronym{ICC} profile}{profile, \acronym{ICC}}% \genidx{colorspace!CIELUV@\acronym{CIELUV}}% \item For grayscale or color input images \emph{with} \acronym{ICC}~profiles the default is to use \acronym{CIELUV}~colorspace. \genidx{color cube!RGB@\acronym{RGB}}% \gensee{RGB@\acronym{RGB} color cube}{color cube, \acronym{RGB}}% \item Images \emph{without} color profiles and floating-point images are blended in the trivial luminance interval (grayscale) or \acronym{RGB}-color cube by default. \end{itemize} On the order of fast to slow computation, \App{} supports the following blend colorspaces. \begin{description} \item[\itempar{\code{identity} \\ \code{id} \\ \code{unit}}]\itemend Compute blended colors in a na\"ive way sidestepping any dedicated colorspace. \begin{itemize} \genidx{luminance interval!trivial}% \item Use trivial, 1-dimensional luminance interval (see \equationabbr~\fullref{equ:trivial-luminance-blend}) for grayscale images and \genidx{color cube!\acronym{RGB}}% \genidx{sRGB@\acronym{sRGB}}% \item for color images utilize 3-dimensional \acronym{RGB}-cube (see \equationabbr~\fullref{equ:trivial-rgb-blend}) spanned by the input \acronym{ICC}~profile or \acronym{sRGB} if no profiles are present. In the latter case, consider passing option~\flexipageref{\option{--fallback-profile}}{opt:fallback-profile} to force a different profile than \acronym{sRGB} upon all input images. \end{itemize} \genidx{colorspace!\acronym{CIEL*a*b*}}% \gensee{CIEL*a*b*@\acronym{CIEL*a*b*} colorspace}{colorspace, \acronym{CIEL*a*b*}}% \item[\itempar{\code{lab} \\ \code{cielab} \\ \code{lstar} \\ \code{l-star}}]\itemend Blend pixels in the \acronym{CIEL*a*b*} colorspace. \genidx{colorspace!\acronym{CIEL*u*v*}}% \gensee{CIEL*u*v*@\acronym{CIEL*u*v*} colorspace}{colorspace, \acronym{CIEL*u*v*}}% \item[\itempar{\code{luv} \\ \code{cieluv}}]\itemend Blend pixels in the \acronym{CIEL*u*v*} colorspace. \genidx{colorspace!\acronym{CIECAM02}}% \gensee{CIECAM02@\acronym{CIECAM02} colorspace}{colorspace, \acronym{CIECAM02}}% \item[\itempar{\code{ciecam} \\ \code{ciecam02} \\ \code{jch}}]\itemend Blend pixels in the \acronym{CIECAM02} colorspace. \end{description} \ifenblend \genidx{optimizer!seam-line}% \begin{restrictedmaterial}{\application{Enblend} only.} Please keep in mind that by using different blend colorspaces, blending may not only change the colors of the output image, but \application{Enblend} may choose different seam line routes as some seam-line optimizers are guided by image differences, which are different when viewed in different colorspaces. \end{restrictedmaterial} \fi \label{opt-ciecam}% \optidx{--ciecam}% \shoptidx{-c}{--ciecam}% \item[\itempar{-c \\ --ciecam}]\itemend Deprecated. Use \sample{--blend-colorspace=ciecam} instead. To emulate the negated option~\option{--no-ciecam}\optidx{--no-ciecam} use \code{--blend-colorspace=identity}. \label{opt:depth}% \optidx[\defininglocation]{--depth}% \shoptidx{-d}{--depth}% \genidx{bits per channel}% \gensee{channel!width}{channel, depth}% \genidx{channel!depth}% \item[\itempar{-d \metavar{DEPTH} \\ --depth=\metavar{DEPTH}}]\itemend Force the number of bits per channel and the numeric format of the output image, this is, the \metavar{DEPTH}. The number of bits per channel is also known as ``channel width'' or ``channel depth''. \genidx{requantization}% \App{} always uses a smart way to change the channel depth to assure highest image quality at the expense of memory, whether requantization is implicit because of the output format or explicit through option~\option{--depth}. \begin{itemize} \item If the output-channel depth is larger than the input-channel depth of the input images, the input images' channels are widened to the output channel depth immediately after loading, that is, as soon as possible. \App{} then performs all blending operations at the output-channel depth, thereby preserving minute color details which can appear in the blending areas. \item If the output-channel depth is smaller than the input-channel depth of the input images, the output image's channels are narrowed only right before it is written to the output \metavar{FILE}, that is, as late as possible. Thus the data benefits from the wider input channels for the longest time. \end{itemize} All \metavar{DEPTH} specifications are valid in lowercase as well as uppercase letters. For integer format, use \begin{description} \item[\code{8}]\itemx[\code{uint8}]\itemend Unsigned 8~bit; range: $0\dots255$ \item[\code{int16}]\itemend Signed 16~bit; range: $-32768\dots32767$ \item[\code{16}]\itemx[\code{uint16}]\itemend Unsigned 16~bit; range: $0\dots65535$ \item[\code{int32}]\itemend Signed 32~bit; range: $-2147483648\dots2147483647$ \item[\code{32}]\itemx[\code{uint32}]\itemend Unsigned 32~bit; range: $0\dots4294967295$ \end{description} %% Minimum positive normalized value: 2^(2 - 2^k) %% Epsilon: 2^(1 - n) %% Maximum finite value: (1 - 2^(-n)) * 2^(2^k) For floating-point format, use \begin{description} \genidx{IEEE754@\acronym{IEEE754}!single precision float}% \gensee{single precision float (\acronym{IEEE754})}{\acronym{IEEE754}, single precision float}% \item[\code{r32}]\itemx[\code{real32}]\itemx[\code{float}]\itemend %% IEEE single: 32 bits, n = 24, k = 32 - n - 1 = 7 \acronym{IEEE754} single precision floating-point, 32~bit wide, 24~bit significant; \begin{compactitemize} \item Minimum normalized value: \semilog{1.2}{-38} \item Epsilon: \semilog{1.2}{-7} \item Maximum finite value: \semilog{3.4}{38} \end{compactitemize} \genidx{IEEE754@\acronym{IEEE754}!double precision float}% \gensee{double precision float (\acronym{IEEE754})}{\acronym{IEEE754}, double precision float}% \item[\code{r64}]\itemx[\code{real64}]\itemx[\code{double}]\itemend %% IEEE double: 64 bits, n = 53, k = 64 - n - 1 = 10 \acronym{IEEE754} double precision floating-point, 64~bit wide, 53~bit significant; \begin{compactitemize} \item Minimum normalized value: \semilog{2.2}{-308} \item Epsilon: \semilog{2.2}{-16} \item Maximum finite value: \semilog{1.8}{308} \end{compactitemize} \end{description} If the requested \metavar{DEPTH} is not supported by the output file format, \App{} warns and chooses the \metavar{DEPTH} that matches best. \genidx{OpenEXR@\acronym{OpenEXR}!data format}% \begin{restrictedmaterial}{Versions with \acronym{OpenEXR} read\slash write support only.} \noindent The \acronym{OpenEXR} data format is treated as \acronym{IEEE754}~float internally. Externally, on disk, \acronym{OpenEXR} data is represented by ``half'' precision floating-point numbers. %% ILM half: 16 bits, n = 10, k = 16 - n - 1 = 5 \genidx{OpenEXR@\acronym{OpenEXR}!half precision float}% \gensee{half precision float (\acronym{OpenEXR})}{\acronym{OpenEXR}, half precision float}% \uref{\openexrcomfeatures}{\acronym{OpenEXR}} half precision floating-point, 16~bit wide, 10~bit significant; \begin{compactitemize} \item Minimum normalized value: \semilog{9.3}{-10} \item Epsilon: \semilog{2.0}{-3} \item Maximum finite value: \semilog{4.3}{9} \end{compactitemize} \end{restrictedmaterial} \label{opt:f}% \optidx[\defininglocation]{-f}% \genidx{size!canvas}% \genidx{output image!set size}% \item[-f \metavar{WIDTH}x\metavar{HEIGHT}% \optional{+x\metavar{XOFFSET}+y\metavar{YOFFSET}}]\itemend Ensure that the minimum ``canvas'' size of the output image is at least \metavar{WIDTH}\classictimes\metavar{HEIGHT}. Optionally specify the \metavar{XOFFSET} and \metavar{YOFFSET} of the canvas, too. \prgidx{nona \textrm{(Hugin)}}% This option only is useful when the input images are cropped \acronym{TIFF} files, such as those produced by \command{nona}. Note that option~\option{-f} neither rescales the output image, nor shrinks the canvas size below the minimum size occupied by the union of all input images. \label{opt:g}% \optidx[\defininglocation]{-g}% \genidx{alpha channel!associated}% \gensee{associated alpha channel}{alpha channel, associated}% \gensee{unassociated alpha channel}{alpha channel, associated}% \item[-g] Save alpha channel as ``associated''. See the \uref{\awaresystemsbeextrasamples}{\acronym{TIFF} documentation} for an explanation. \appidx{Gimp}% \appidx{Cinepaint}% \application{The Gimp} before version~2.0 and \application{CinePaint} (see \appendixName~\fullref{sec:helpful-programs}) exhibit unusual behavior when loading images with unassociated alpha channels. Use option~\option{-g} to work around this problem. With this flag \App{} will create the output image with the ``associated alpha tag'' set, even though the image is really unassociated alpha. \label{opt:wrap}% \optidx[\defininglocation]{--wrap}% \shoptidx{-w}{--wrap}% \genidx{wrap around}% \item[\itempar{-w \optional{\metavar{MODE}} \\ --wrap\optional{=\metavar{MODE}}}]\itemend Blend around the boundaries of the panorama, or ``wrap around''. As this option significantly increases memory usage and computation time only use it, if the panorama will be \begin{compactitemize} \item consulted for any kind measurement, this is, all boundaries must match as accurately as possible, or \item printed out and the boundaries glued together, or \genidx{virtual reality}% \gensee{VR@\acronym{VR}}{virtual reality}% \item fed into a virtual reality~(\acronym{VR}) generator, which creates a seamless environment. \end{compactitemize} \noindent Otherwise, always avoid this option! With this option \App{} treats the set of input images (panorama) of width~$w$ and height~$h$ as an infinite data structure, where each pixel~$P(x, y)$ of the input images represents the set of pixels~$S_P(x, y)$. \begin{geeknote} \genidx{Born@\propername{Born, Max}}% \genidx{Karman@\propername{von~K\'arm\'an, Theodore}}% Solid-state physicists will be reminded of the \uref{\wikipediabornvonkarman}{\propername{Born}-\propername{von~K\'arm\'an} boundary condition}. \end{geeknote} \metavar{MODE} takes the following values: \begin{codelist} \item[\itempar{none \\ open}]\itemend This is a ``no-op''; it has the same effect as not giving \sample{--wrap} at all. The set of input images is considered open at its boundaries. \item[horizontal]\itemend Wrap around horizontally: \[ S_P(x, y) = \{P(x + m w, y): m \in Z\}. \] \genidx{panorama!360\angulardegree!horizontal}% \gensee{360@360\angulardegree{}!horizontal panorama}{panorama, 360\angulardegree}% This is useful for 360\angulardegree{} horizontal panoramas as it eliminates the left and right borders. \item[vertical]\itemend Wrap around vertically: \[ S_P(x, y) = \{P(x, y + n h): n \in Z\}. \] \genidx{panorama!360\angulardegree!vertical}% \gensee{360@360\angulardegree{}!vertical panorama}{panorama, 360\angulardegree}% This is useful for 360\angulardegree{} vertical panoramas as it eliminates the top and bottom borders. \item[\itempar{both \\ horizontal+vertical \\ vertical+horizontal}]\itemend Wrap around both horizontally and vertically: \[ S_P(x, y) = \{P(x + m w, y + n h): m, n \in Z\}. \] In this mode, both left and right borders, as well as top and bottom borders, are eliminated. \end{codelist} Specifying \sample{--wrap} without \metavar{MODE} selects horizontal wrapping. \end{codelist} \genidx[\rangeendlocation]{advanced options} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enblend-mask-generation-options.tex0000644000175000017500000002141012676175561020661 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \subsection[Mask Generation Options]{\label{sec:mask-generation-options}% \genidx[\rangebeginlocation]{mask generation options}% \genidx{options!mask generation}% Mask Generation Options} These options control the generation and the usage of masks. \begin{codelist} \label{opt:coarse-mask}% \optidx[\defininglocation]{--coarse-mask}% \genidx{mask!coarse} \gensee{coarse mask}{mask, coarse}% \item[--coarse-mask\optional{=\metavar{FACTOR}}]\itemend Use a scaled-down or ``coarse'' version of the input images to create the seam line. This option reduces the number of computations necessary to compute the seam line and the amount of memory necessary to do so. It is the default. If omitted \metavar{FACTOR} defaults to \val{val:default-coarseness-factor}, this means, option~\option{--coarse\hyp mask} shrinks the overlapping \emph{areas} by a factor of $\val{val:default-coarseness-factor}\classictimes\val{val:default-coarseness-factor}$. With $\metavar{FACTOR} = 8$ the total memory allocated during a run of \App{} shrinks approximately by 80\% and the maximum amount of memory in use at a time is decreased to some 40\% in comparison to a full-size (``fine'') mask. Valid range: $\metavar{FACTOR} = 1, 2, 3, \dots$, where 1 reproduces \code{--fine\hyp mask}. Also see the negated option, \flexipageref{\sample{--fine-mask}}{opt:fine-mask} and \tableName~\ref{tab:mask-generation}. \begin{table} \begin{tabular}{lp{.333\linewidth}p{.333\linewidth}} \hline \multicolumn{1}{c|}{Active Options} & \multicolumn{1}{c|}{\option{--no-optimize}} & \multicolumn{1}{c}{\option{--optimize}} \\ \hline\extraheadingsep \option{--fine-mask} & Use \acronym{NFT} mask. & Vectorize \acronym{NFT} mask, optimize vertices with simulated annealing and \propername{Dijkstra's} shortest path algorithm, fill vector contours to recover mask. \\ \option{--coarse-mask} & Scale down overlap region, compute \acronym{NFT} mask and vectorize it, fill vector contours. & Scale down overlap region, vectorize \acronym{NFT} mask, optimize vertices with simulated annealing and \propername{Dijkstra's} shortest path algorithm, fill vector contours to recover mask. \end{tabular} \caption[Mask generation options]{\label{tab:mask-generation}% \genidx{nearest-feature transform (\acronym{NFT})}% \genidx[\summarylocation]{mask!generation}% Various options that control the generation of masks. All mask computations are based on the Nearest-Feature Transformation (\acronym{NFT}) of the overlap region.} \end{table} \label{opt:fine-mask}% \optidx[\defininglocation]{--fine-mask}% \genidx{mask!fine} \gensee{fine mask}{mask, fine}% \item[--fine-mask]\itemend Instruct \App{} to employ the full-size images to create the seam line, which can be slow. Use this option, for example, if you have very narrow overlap regions. Also see option~\flexipageref{\option{--coarse-mask}}{opt:coarse-mask} and \tableName~\ref{tab:mask-generation}. \label{opt:load-masks}% \optidx[\defininglocation]{--load-masks}% \genidx{mask!load}% \gensee{load mask}{mask, load}% \item[--load-masks\optional{=\metavar{IMAGE-TEMPLATE}}]\itemend Instead of generating masks, load those in \metavar{IMAGE\hyp{}TEMPLATE}. The default is \mbox{\sample{\val{val:default-mask-template}}}. The mask images must be 8~bit grayscale images. See option~\flexipageref{\option{--save-masks}}{opt:save-masks} below for details. \label{opt:optimize}% \optidx[\defininglocation]{--optimize}% \genidx{optimize!seam}% \gensee{seam optimization}{optimize, seam}% \item[--optimize]\itemend Use a multi-strategy approach to route the seam line around mismatches in the overlap region. This is the default. \tableName~\ref{tab:optimizer-strategies} explains these strategies; also see Table~\ref{tab:mask-generation}. \begin{table} \begin{tabular}{p{.35\linewidth}p{.55\linewidth}} \hline \multicolumn{1}{c|}{Algorithm} & \multicolumn{1}{c}{Tuning Parameters} \\ \hline\extraheadingsep Simulated Annealing & Tune with option~\option{--anneal} = \metavar{TAU} : \metavar{DELTA-E-MAX} : \metavar{DELTA-E-MIN} : \metavar{K-MAX}. \uref{\wikipediasimulatedannealing}{Simulated-Annealing}. \fixme{Explain Simulated-Annealing!} \\ \propername{Dijkstra} Shortest Path & Tune with option~\option{--dijkstra} = \metavar{RADIUS}. \uref{\wikipediadijkstraalgorithm}{\propername{Dijkstra} algorithm}. \fixme{Explain \propername{Dijkstra} algorithm!} \end{tabular} \caption[Optimizer strategies]{\label{tab:optimizer-strategies}% \genidx[\summarylocation]{optimize!strategy}% \App{}'s strategies to optimize the seam lines between overlapping images.} \end{table} \genidx{optimize!seam}% \gensee{seam optimization}{optimize, seam}% \genidx{nearest-feature transform (\acronym{NFT})}% Option~\option{--no-optimize}\optidx[\defininglocation]{--no-optimize} negates \option{--optimize} and thus turns off seam line optimization. Combined with option~\flexipageref{\option{--fine-mask}}{opt:fine-mask} this will produce the same type of mask as \App{}~version~2.5, namely the result of a Nearest-Feature Transform (\acronym{NFT}). \label{opt:save-masks}% \optidx[\defininglocation]{--save-masks}% \genidx{mask!save}% \gensee{save mask}{mask, save}% \item[--save-masks\optional{=\metavar{IMAGE-TEMPLATE}}]\itemend Save the generated masks to \metavar{IMAGE-TEMPLATE}, which defaults to \mbox{\sample{\val{val:default-mask-template}}}. \App{} saves masks as 8~bit grayscale, i.e.\ single channel images. For accuracy we recommend to choose a lossless format. Use this option if you wish to edit the location of the seam line by hand. This will give you images of the right sizes that you can edit to make your changes. Later, use option~\flexipageref{\option{--load-masks}}{opt:load-masks} to blend the project with your custom seam lines. \genidx{save mask!only}% \gensee{only save mask}{save mask, only}% \begin{sloppypar} \App{} will stop after saving all masks unless option~\flexipageref{\option{--output}}{opt:output} is given, too. With both options given, this is, \sample{--save-masks} and \sample{--output}, \App{} saves all masks and then proceeds to blend the output image. \end{sloppypar} \begin{geeknote} \metavar{IMAGE-TEMPLATE} defines a template that is expanded for each input file. In a template a percent sign (\sample{\%}) introduces a variable part. All other characters are copied literally. Lowercase letters refer to the name of the respective input file, whereas uppercase ones refer to the name of the output file (see Section~\fullref{sec:common-options}). \tableName~\ref{tab:mask-template-characters} lists all variables. A fancy mask filename template could look like this: \begin{literal} \%D/mask-\%02n-\%f.tif \end{literal} It puts the mask files into the same directory as the output file~\sample{\%D}, generates a two-digit index~\sample{\%02n} to keep the mask files nicely sorted, and decorates the mask filename with the name of the associated input file~\sample{\%f} for easy recognition. \end{geeknote} \label{opt:visualize}% \optidx[\defininglocation]{--visualize}% \genidx{mask!optimization visualization}% \gensee{visualization of mask}{mask, optimization visualization}% \item[--visualize\optional{=\metavar{VISUALIZE-TEMPLATE}}]\itemend Create an image according to \metavar{VISUALIZE-TEMPLATE} that visualizes the un-optimized mask and the applied optimizations (if any). The default is \mbox{\sample{\val{val:default-visualize-template}}}. This image will show \App{}'s view of the overlap region and how it decided to route the seam line. If you are experiencing artifacts or unexpected output, it may be useful to include this visualization image in your bug report. For a detailed description of the image, consult \chapterName~\fullref{sec:visualization-image}. \begin{geeknote} \metavar{VISUALIZE-TEMPLATE} defines a template that is expanded for each input file. In a template, a percent sign (\sample{\%}) introduces a variable part; all other characters are copied literally. Lowercase letters refer to the name of the respective input file, whereas uppercase ones refer to the name of the output file (see option~\flexipageref{\option{--output}}{opt:output}). \tableName~\fullref{tab:mask-template-characters} lists all variables. \end{geeknote} \end{codelist} \input{common-mask-template-characters} \genidx[\rangeendlocation]{mask generation options} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/index-use.tex0000644000175000017500000000274112560674445014403 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \cleardoublepage{} \RaggedRight \phantomsection \addcontentsline{toc}{chapter}{Indices} \phantomsection \addcontentsline{toc}{section}{\ahrefloc{sec:syncomm-index}{Syntactic Comment Index}} \label{sec:syncomm-index}% \printindex[syncomm]% \gensea{helpful programs}{Program/Application Index} \phantomsection \addcontentsline{toc}{section}{\ahrefloc{sec:program-index}{Program/Application Index}} \label{sec:program-index}% \ifhevea \printindex[program] If a program belongs to a larger package, it has its association mentioned in parenthesis. \else \printindex[program][If a program belongs to a larger package, it has its association mentioned in parenthesis.\par]% \fi \phantomsection \addcontentsline{toc}{section}{\ahrefloc{sec:option-index}{Option Index}} \label{sec:option-index} \ifhevea \printindex[option]% \else \printindex[option][Locations marked like \underline{12} indicate the place of the option's genuine description.\par]% \fi \phantomsection \addcontentsline{toc}{section}{\ahrefloc{sec:general-index}{General Index}} \label{sec:general-index} \ifhevea \printindex[general]% \else \printindex[general][Locations marked like \underline{12} indicate the location where a term gets introduced or defined. Tables, lists, etc.\ that summarize material are indicated like \textsl{34}.\par]% \fi %%% Local Variables: %%% fill-column: 96 %%% mode: latex %%% End: enblend-enfuse-4.2/doc/examples/0000755000175000017500000000000012676432767013661 500000000000000enblend-enfuse-4.2/doc/examples/enfuse/0000755000175000017500000000000012676432770015140 500000000000000enblend-enfuse-4.2/doc/examples/enfuse/templated_power.cc0000644000175000017500000000404012641706002020540 00000000000000// Copyright (C) 2014-2016 Christoph L. Spiel // // This file is part of Enblend. // // Enblend 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. // // Enblend 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 Enblend; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include // std::max() #include // macro M_LN2, std::exp(), std::abs() #include // std::cerr #include "exposure_weight_base.h" // macro FWHM_GAUSSIAN, class ExposureWeight template inline static double ipower(double x) { return x * ipower(x); } template <> double ipower<0>(double) { return 1.0; } template struct TemplatedPower : public ExposureWeight { void initialize(double y_optimum, double width, ExposureWeight::argument_const_iterator arguments_begin, ExposureWeight::argument_const_iterator arguments_end) override { if (arguments_begin != arguments_end) { std::cerr << "warning: weight function \"power#\" does not take any parameters" << std::endl; } const double fwhm = 2.0 / std::exp(M_LN2 / static_cast(n)); ExposureWeight::initialize(y_optimum, width * FWHM_GAUSSIAN / fwhm, arguments_begin, arguments_end); } double weight(double y) override { return std::max(1.0 - ipower(std::abs(normalize(y))), 0.0); } }; TemplatedPower<2> tpower2; TemplatedPower<3> tpower3; TemplatedPower<4> tpower4; enblend-enfuse-4.2/doc/examples/enfuse/sinc.cc0000644000175000017500000001216612641706002016311 00000000000000// Copyright (C) 2014-2016 Christoph L. Spiel // // This file is part of Enblend. // // Enblend 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. // // Enblend 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 Enblend; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include // std::max() #include // std::array<> #include #include // std::abs(), std::sqrt() #include // std::unary_function<> #include // std::cerr #include // std::numeric_limits<> #include // std::istringstream #include "exposure_weight_base.h" // macro FWHM_GAUSSIAN, class ExposureWeight #include "root_finding.hh" // root_finding::dekker() // sinus_cardinalis(x) = if(x == 0, 1, sin(x) / x) inline static double sinus_cardinalis(double x) { return x == 0.0 ? 1.0 : std::sin(x) / x; } // scaled_sinc(x) = sinus_cardinalis(Pi * x) inline static double scaled_sinc(double x) { return sinus_cardinalis(M_PI * x); } // truncated_sinc(x) = if(abs(x) >= 1, 0, scaled_sinc(x)) inline static double truncated_sinc(double x) { return std::fabs(x) >= 1.0 ? 0.0 : scaled_sinc(x); } class Function : public std::unary_function { public: virtual double operator()(double) const = 0; virtual double fwhm() const = 0; virtual ~Function() {} protected: double find_fwhm(double x0, double x1) const { assert(x0 >= 0.0); const double y_half = root_finding::dekker(x0, x1, [&](double x) {return operator()(x) - 0.5;}); assert(std::fabs(operator()(y_half) - 0.5) < std::sqrt(std::numeric_limits::epsilon())); return 2.0 * y_half; } }; class Sinc : public Function { public: double operator()(double x) const {return truncated_sinc(x);} double fwhm() const {return 1.2067091288032283952915076867831260818;} }; class PowerSinc : public Function { public: PowerSinc() : argument_exponent(1.0), exponent(1.0) {} PowerSinc(double a, double e) : argument_exponent(a), exponent(e) { assert(argument_exponent >= 1.0); assert(exponent >= 0.0); } double operator()(double x) const { return std::pow(truncated_sinc(std::pow(x, argument_exponent)), exponent); } double fwhm() const {return find_fwhm(0.0, 1.0);} private: const double argument_exponent; const double exponent; }; //////////////////////////////////////////////////////////////////////////////// class SincWeight : public ExposureWeight { public: void initialize(double y_optimum, double width, ExposureWeight::argument_const_iterator arguments_begin, ExposureWeight::argument_const_iterator arguments_end) override { if (arguments_begin != arguments_end) { std::cerr << "warning: weight function does not take any parameters" << std::endl; } ExposureWeight::initialize(y_optimum, width * FWHM_GAUSSIAN / sinc.fwhm(), arguments_begin, arguments_end); } double weight(double y) override { return sinc(std::abs(normalize(y))); } private: Sinc sinc; }; class PowerSincWeight : public ExposureWeight { typedef ExposureWeight super; public: PowerSincWeight() : sinc(nullptr) {} PowerSincWeight(const PowerSincWeight&) = delete; PowerSincWeight& operator=(const PowerSincWeight&) = delete; ~PowerSincWeight() {delete sinc;} void initialize(double y_optimum, double width, super::argument_const_iterator arguments_begin, super::argument_const_iterator arguments_end) override { std::array exponents = {1.0, 1.0}; super::argument_const_iterator argument = arguments_begin; for (double e : exponents) { if (argument == arguments_end) { break; } std::istringstream iss(*argument++); if (!(iss >> e)) { throw super::error("non-numeric exponent"); } } sinc = new PowerSinc(exponents.at(0), exponents.at(1)); ExposureWeight::initialize(y_optimum, width * FWHM_GAUSSIAN / sinc->fwhm(), arguments_begin, arguments_end); } double weight(double y) override { return sinc->operator()(std::abs(normalize(y))); } private: PowerSinc* sinc; }; //////////////////////////////////////////////////////////////////////////////// SincWeight sinc; PowerSincWeight power_sinc; enblend-enfuse-4.2/doc/examples/enfuse/Makefile.userweight0000644000175000017500000000230512676432457020707 00000000000000# -*- makefile -*- CXX := g++ CXXFLAGS := -pthread -I/usr/include/OpenEXR -std=gnu++1y -pipe -march=native -g -fsanitize=undefined -O0 -fno-omit-frame-pointer -Wp,-Werror -Wextra -Warray-bounds -Wno-unused-parameter -Wformat -g -DDEBUG -fpic LD := $(CXX) LDFLAGS := -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -g -L/usr/lib/x86_64-linux-gnu -L/home/cspiel/lib -Wl,-rpath=/home/cspiel/lib -L/home/cspiel/scm-projects/boost-git/stage/lib -Wl,-rpath=/home/cspiel/scm-projects/boost-git/stage/lib -shared SOURCES := linear.cc fixed_power.cc templated_power.cc variable_power.cc sinc.cc OBJECTS := $(patsubst %.cc,%.o,$(SOURCES)) SHARED_OBJECTS := $(patsubst %.cc,%.so,$(SOURCES)) .PHONY: all all: $(SHARED_OBJECTS) .PHONY: clean clean: $(RM) *.so *.o .PHONY: distclean distclean: clean $(RM) *~ %.so: %.o $(LD) $(LDFLAGS) -Wl,-soname,$@ -o $@ $^ %.o: %.cc $(CXX) $(CXXFLAGS) -c $< # All-in-one library userweights.so: $(OBJECTS) sinc.o: sinc.cc root_finding.hh # User-weight `tabular' is not part of SOURCES, because it relies on a # GSL header, which may not available on every system. tabular.so: tabular.o interpolator.o tabular.o: tabular.cc interpolator.hh interpolator.cc: interpolator.hh enblend-enfuse-4.2/doc/examples/enfuse/variable_power.cc0000644000175000017500000000463512663540207020367 00000000000000// Copyright (C) 2014-2016 Christoph L. Spiel // // This file is part of Enblend. // // Enblend 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. // // Enblend 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 Enblend; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // Note: The functionality encoded in this C++-file does *not* require // "variable_power.cl", an OpenCL-file which defines the same weight // function using the OpenCL-extension mechanism of Enfuse. #include // std::max() #include // errno #include // macro M_LN2, std::exp(), std::abs(), std::pow() #include #include "exposure_weight_base.h" // macro FWHM_GAUSSIAN, class ExposureWeight class VariablePower : public ExposureWeight { typedef ExposureWeight super; public: void initialize(double y_optimum, double width, super::argument_const_iterator arguments_begin, super::argument_const_iterator arguments_end) override { if (arguments_begin == arguments_end) { exponent = 2.0; } else { char* tail; errno = 0; exponent = strtod(arguments_begin->c_str(), &tail); if (*tail != 0 || errno != 0) { throw super::error("non-numeric exponent"); } if (exponent <= 0.0 || exponent > 4.0) { throw super::error("exponent x out of range 0 < x <= 4"); } } const double fwhm = 2.0 / std::exp(M_LN2 / exponent); super::initialize(y_optimum, width * FWHM_GAUSSIAN / fwhm, arguments_begin, arguments_end); } double weight(double y) override { return std::max(1.0 - std::pow(std::abs(normalize(y)), exponent), 0.0); } private: double exponent; }; VariablePower vpower; enblend-enfuse-4.2/doc/examples/enfuse/Makefile.am0000644000175000017500000000047512640252627017112 00000000000000datadir = $(docdir)/examples/enfuse data_DATA = \ Makefile.userweight \ README.userweight \ ../../../src/exposure_weight_base.h \ fixed_power.cc linear.cc \ root_finding.hh sinc.cc \ tabular.cc templated_power.cc \ variable_power.cc EXTRA_DIST = $(data_DATA) enblend-enfuse-4.2/doc/examples/enfuse/Makefile.in0000644000175000017500000003651312676432431017127 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/examples/enfuse DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/Makefile.userweight.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/_ac_latex_test.m4 \ $(top_srcdir)/m4/ac_latex_class.m4 \ $(top_srcdir)/m4/ac_latex_package.m4 \ $(top_srcdir)/m4/ac_prog_ar.m4 \ $(top_srcdir)/m4/ac_prog_latex.m4 \ $(top_srcdir)/m4/ac_type_sig_atomic_t.m4 \ $(top_srcdir)/m4/ax_boost_base.m4 \ $(top_srcdir)/m4/ax_cxx_as_const.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/ax_openmp.m4 \ $(top_srcdir)/m4/ax_prog_perl_modules.m4 \ $(top_srcdir)/m4/ax_with_prog.m4 $(top_srcdir)/m4/lrint.m4 \ $(top_srcdir)/m4/lrintf.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = Makefile.userweight CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(datadir)" DATA = $(data_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONVERT = @CONVERT@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_IMPLEMENTATION = @DL_IMPLEMENTATION@ DOT = @DOT@ DVIPDF = @DVIPDF@ DVIPS = @DVIPS@ DYNAMIC_TEX_PREAMBLE = @DYNAMIC_TEX_PREAMBLE@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_LIBS = @EXTRA_LIBS@ GNUPLOT = @GNUPLOT@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_INLINE = @HAVE_INLINE@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LATEX = @LATEX@ LATEX2HTML = @LATEX2HTML@ LATEX2HTML_LIBDIR = @LATEX2HTML_LIBDIR@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ M4 = @M4@ MAKEINDEX = @MAKEINDEX@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ OPENEXR_LIBS = @OPENEXR_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SPLITHTML = @SPLITHTML@ STRIP = @STRIP@ SVGCONVERT = @SVGCONVERT@ TEXLOGANALYSER = @TEXLOGANALYSER@ VERSION = @VERSION@ VIGRAIMPEX_LIB = @VIGRAIMPEX_LIB@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ amsmath = @amsmath@ bindir = @bindir@ bold_extra = @bold_extra@ boretti_classesansparametre = @boretti_classesansparametre@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ color = @color@ datadir = $(docdir)/examples/enfuse datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enumitem = @enumitem@ exec_prefix = @exec_prefix@ float = @float@ footnote = @footnote@ graphicx = @graphicx@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hyperref = @hyperref@ hyphenat = @hyphenat@ ifpdf = @ifpdf@ includedir = @includedir@ index = @index@ infodir = @infodir@ install_sh = @install_sh@ latex = @latex@ latexsym = @latexsym@ libdir = @libdir@ libexecdir = @libexecdir@ listings = @listings@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ microtype = @microtype@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ ragged2e = @ragged2e@ refrep = @refrep@ report = @report@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shorttoc = @shorttoc@ srcdir = @srcdir@ suffix = @suffix@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ url = @url@ xstring = @xstring@ data_DATA = \ Makefile.userweight \ README.userweight \ ../../../src/exposure_weight_base.h \ fixed_power.cc linear.cc \ root_finding.hh sinc.cc \ tabular.cc templated_power.cc \ variable_power.cc EXTRA_DIST = $(data_DATA) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/examples/enfuse/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/examples/enfuse/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): Makefile.userweight: $(top_builddir)/config.status $(srcdir)/Makefile.userweight.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-dataDATA: $(data_DATA) @$(NORMAL_INSTALL) @list='$(data_DATA)'; test -n "$(datadir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(datadir)'"; \ $(MKDIR_P) "$(DESTDIR)$(datadir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(datadir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(datadir)" || exit $$?; \ done uninstall-dataDATA: @$(NORMAL_UNINSTALL) @list='$(data_DATA)'; test -n "$(datadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(datadir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(datadir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dataDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dataDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dataDATA install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am \ uninstall-dataDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: enblend-enfuse-4.2/doc/examples/enfuse/fixed_power.cc0000644000175000017500000000365412641706002017672 00000000000000// Copyright (C) 2014-2016 Christoph L. Spiel // // This file is part of Enblend. // // Enblend 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. // // Enblend 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 Enblend; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include // std::max() #include // macro M_LN2, std::exp(), std::abs(), std::pow() #include // std::cerr #include "exposure_weight_base.h" // macro FWHM_GAUSSIAN, class ExposureWeight template struct FixedPower : public ExposureWeight { void initialize(double y_optimum, double width, ExposureWeight::argument_const_iterator arguments_begin, ExposureWeight::argument_const_iterator arguments_end) override { if (arguments_begin != arguments_end) { std::cerr << "warning: weight function \"power#\" does not take any parameters" << std::endl; } const double fwhm = 2.0 / std::exp(M_LN2 / static_cast(exponent)); ExposureWeight::initialize(y_optimum, width * FWHM_GAUSSIAN / fwhm, arguments_begin, arguments_end); } double weight(double y) override { return std::max(1.0 - std::pow(std::abs(normalize(y)), static_cast(exponent)), 0.0); } }; FixedPower<2> power2; FixedPower<3> power3; FixedPower<4> power4; enblend-enfuse-4.2/doc/examples/enfuse/README.userweight0000644000175000017500000000700312637736744020132 00000000000000This directory contains all example exposure weight functions mentioned in the User Manual. Just as a quick refresher, remember that all of these are loaded with --exposure-weight-function=SHARED-OBJECT:SYMBOL[:ARGUMENT[:...]] * linear.cc This is a very simple weight function with a roof-like shape. Function "linear" does not take any extra ARGUMENT. * fixed_power.cc This module defines three power-weights "power2", "power3" and "power4" in the form (1 - Y^n), where n is 2, 3, and 4. All are derived from the same template class FixedPower. None of the functions take any extra ARGUMENT. * templated_power.cc This module duplicates the functionality of "fixed_power.cc" to define the weights "tpower2", "tpower3" and "tpower4". However, it uses a recursively evaluating template class to implement the integral power function. Again, none of the functions take any extra ARGUMENT. * variable_power.cc Here, we define the single weight function "vpower", which implements (1 - Y^N), where N is a free parameter and ARGUMENT. Of course the functionality is a super-set of "power#", and "tpower#", allowing even for fractional exponents N. * sinc.cc This module defines two weight functions based on the truncated, scaled sinc function: / sin(Pi * Y) / (Pi * Y) for Y <> 0 and |Y| < 1 sinc(Y) := | 1 for Y == 0 \ 0 for |Y| >= 1 The simple weight "sinc" takes no extra ARGUMENT. The second function, "power_sinc", implements sinc(Y^N)^M, where N and M act as free parameters and are ARGUMENTs. - tabular.cc Linearly interpolate weights between given (Y, w)-pairs. The pairs are either defined in a file (mode: "file") of one pair per line or directly at the command line (mode: "immediate"). In "file"-mode, separate (Y, w)-pairs by white-space. Empty lines, lines of only white-space, and everything after the '#' comment character is skipped. Example: # Trivial example of a weight function defined by isolated data points. 0.0 0.0 0.25 0.125 0.5 1.0 0.75 0.25 1.0 0.0 In "immediate"-mode pass one space-separated pair per element like '0.0 0.0 : 0.25 0.125 : 0.5 1.0 : 0.75 0.25 : 1.0 0.0' or slash-separated pairs '0.0/0.0 : 0.25/0.125 : 0.5/1.0 : 0.75/0.25 : 1.0/0.0' Squeezing out the white-space also saves us quoting against Shell processing: 0.0/0.0:0.25/0.125:0.5/1.0:0.75/0.25:1.0/0.0 Use "Makefile.userweight" as a start to build the examples or your own code. To inspect any exposure-weight function (not just dynamically loaded) pass --parameter=dump-exposure-weight-function to Enfuse. This option instructs Enfuse to evaluate at 21 [default] equidistant points in the interval 0..1, print a three-column report to standard output and exit. Column #1 is the integral point index starting at zero, column #2 is the point at which the function was evaluated ("normalized luminance coordinate") and the last column shows the weight. Use --parameter=exposure-weight-function-points=101 to set the number N (10 <= N <= 10000) of points in the dump. As `--parameter' options always can be collapsed, the short form is --parameter=dump-exposure-weight-function:exposure-weight-function-points=101 Visualize the weight function e.g. with the help of Gnuplot enfuse --parameter=dump-exposure-weight-function:exposure-weight-function-points=101 > weight.data gnuplot gnuplot> plot "weight.data" using 2:3 enblend-enfuse-4.2/doc/examples/enfuse/linear.cc0000644000175000017500000000326712641706002016631 00000000000000// Copyright (C) 2014-2016 Christoph L. Spiel // // This file is part of Enblend. // // Enblend 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. // // Enblend 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 Enblend; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include // std::abs() #include // std::cerr #include "exposure_weight_base.h" // macro FWHM_GAUSSIAN, class ExposureWeight struct Linear : public ExposureWeight { void initialize(double y_optimum, double width_parameter, ExposureWeight::argument_const_iterator arguments_begin, ExposureWeight::argument_const_iterator arguments_end) override { if (arguments_begin != arguments_end) { std::cerr << "warning: weight function \"linear\" does not take any parameters" << std::endl; } ExposureWeight::initialize(y_optimum, width_parameter * FWHM_GAUSSIAN, arguments_begin, arguments_end); } double weight(double y) override { const double z = std::abs(normalize(y)); return z <= 1.0 ? 1.0 - z : 0.0; } }; Linear linear; enblend-enfuse-4.2/doc/examples/enfuse/root_finding.hh0000644000175000017500000000476712641706002020060 00000000000000// Copyright (C) 2014-2016 Christoph L. Spiel // // This file is part of Enblend. // // Enblend 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. // // Enblend 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 Enblend; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #ifndef ROOT_FINDING_INCLUDED #define ROOT_FINDING_INCLUDED #include #include // std::abs(), std::sqrt() #include // std::unary_function<> #include // std::numeric_limits<> namespace root_finding { // Rudimentary implementation of Dekker's algorithm template static double dekker(double x0, double x1, function f, double delta = std::sqrt(std::numeric_limits::epsilon()), double epsilon = std::numeric_limits::epsilon()) { assert(x0 <= x1 && "degenerate interval"); assert(f(x0) * f(x1) < 0.0 && "root not bracketed"); while (x1 - x0 >= delta) { const double f0 = f(x0); const double f1 = f(x1); const double root = x1 - f1 * (x1 - x0) / (f1 - f0); const double f_root = f(root); if (std::fabs(f_root) <= epsilon) { return root; } const double middle = (x0 + x1) / 2.0; const double f_middle = f(middle); if (std::fabs(f_root) <= std::abs(f_middle)) { if (f_root * f0 < 0.0) { x1 = root; } else { x0 = root; } } else { if (f_middle * f0 < 0.0) { x1 = middle; } else { x0 = middle; } } } return (x0 + x1) / 2.0; } } // namespace root_finding #endif // ROOT_FINDING_INCLUDED enblend-enfuse-4.2/doc/examples/enfuse/Makefile.userweight.in0000644000175000017500000000146212637736744021322 00000000000000# -*- makefile -*- CXX := @CXX@ CXXFLAGS := @CXXFLAGS@ -fpic LD := $(CXX) LDFLAGS := @LDFLAGS@ -shared SOURCES := linear.cc fixed_power.cc templated_power.cc variable_power.cc sinc.cc OBJECTS := $(patsubst %.cc,%.o,$(SOURCES)) SHARED_OBJECTS := $(patsubst %.cc,%.so,$(SOURCES)) .PHONY: all all: $(SHARED_OBJECTS) .PHONY: clean clean: $(RM) *.so *.o .PHONY: distclean distclean: clean $(RM) *~ %.so: %.o $(LD) $(LDFLAGS) -Wl,-soname,$@ -o $@ $^ %.o: %.cc $(CXX) $(CXXFLAGS) -c $< # All-in-one library userweights.so: $(OBJECTS) sinc.o: sinc.cc root_finding.hh # User-weight `tabular' is not part of SOURCES, because it relies on a # GSL header, which may not available on every system. tabular.so: tabular.o interpolator.o tabular.o: tabular.cc interpolator.hh interpolator.cc: interpolator.hh enblend-enfuse-4.2/doc/examples/enfuse/tabular.cc0000644000175000017500000001647612641706002017017 00000000000000// Copyright (C) 2014-2016 Christoph L. Spiel // // This file is part of Enblend. // // Enblend 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. // // Enblend 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 Enblend; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include // std::max() #include // macro assert() #include // std::isspace() #include // std::ifstream #include // std::cerr #include // std::istringstream #include // std::string #include // std::unordered_map #include // std::vector<> #include "exposure_weight_base.h" // macro FWHM_GAUSSIAN, class ExposureWeight #include "interpolator.hh" // class Interpolator typedef std::pair, std::vector > value_table; static void dump_value_table(value_table a_value_table) { const value_table::first_type& ys = a_value_table.first; const value_table::second_type& ws = a_value_table.second; assert(ys.size() == ws.size()); for (size_t i = 0U; i != ys.size(); ++i) { std::cout << '[' << i << "] " << ys[i] << '\t' << ws[i] << '\n'; } } // Answer whether a_string consists *only* of syntactic white-space // which either is plain white-space or white-space trailed by a // comment character ('#') and an arbitrary string after in until the // end of a_string. static bool is_syntactic_whitespace(const std::string& a_string) { for (auto c : a_string) { if (c == '#') { return true; } if (!isspace(c)) { return false; } } return true; } static value_table read_data_file(const std::string& a_datafile_name) { std::ifstream data_file(a_datafile_name.c_str()); unsigned line_number = 1U; std::string line; std::vector xs; std::vector ys; while (std::getline(data_file, line)) { if (!is_syntactic_whitespace(line)) { std::istringstream iss(line); double x; double y; if (!(iss >> x >> y)) { std::ostringstream error_message; error_message << "data file: \"" << a_datafile_name << "\", line: " << line_number << " - failed to parse (luminance, weight) pair"; std::cerr << error_message.str() << std::endl; } else { xs.push_back(x); ys.push_back(y); } } ++line_number; } return std::make_pair(xs, ys); } static value_table read_data_arguments(ExposureWeight::argument_const_iterator arguments_begin, ExposureWeight::argument_const_iterator arguments_end) { int argument_number = 1; ExposureWeight::argument_const_iterator argument = arguments_begin; std::vector xs; std::vector ys; while (argument != arguments_end) // for (const auto& a : argument_list) { double x; double y; char delimiter; if (sscanf(argument->c_str(), "%lf%lf", &x, &y) == 2 || (sscanf(argument->c_str(), "%lf%c%lf", &x, &delimiter, &y) == 3 && delimiter == '/')) { xs.push_back(x); ys.push_back(y); } else { std::ostringstream error_message; error_message << "immediate data #" << argument_number << " - failed to parse (luminance, weight) pair"; std::cerr << error_message.str() << std::endl; } ++argument; ++argument_number; } return std::make_pair(xs, ys); } class Tabular : public ExposureWeight { typedef ExposureWeight super; public: ~Tabular() {delete interpolator;} void initialize(double y_optimum, double width_parameter, super::argument_const_iterator arguments_begin, super::argument_const_iterator arguments_end) override { if (y_optimum != 0.5) { std::cerr << "Tabular::initialize: warning: ignoring parameter \"--exposure-optimum\"" << std::endl; } if (width_parameter != 0.2) { std::cerr << "Tabular::initialize: warning: ignoring parameter \"--exposure-width\"" << std::endl; } if (arguments_begin == arguments_end) { throw super::error("missing data-source parameter"); } const std::string& data_source_tag = *arguments_begin; if (data_source_tag == "immediate") { super::argument_const_iterator first_data_point = arguments_begin + 1; if (first_data_point == arguments_end) { throw super::error("no data supplied"); } value_table data {read_data_arguments(first_data_point, arguments_end)}; dump_value_table(data); interpolator = new Interpolator(data.first, data.second); } else if (data_source_tag == "file") { super::argument_const_iterator filename = arguments_begin + 1; if (filename == arguments_end) { throw super::error("missing data-file name parameter"); } value_table data {read_data_file(*filename)}; dump_value_table(data); interpolator = new Interpolator(data.first, data.second); } else { throw super::error("unrecognized data-source"); } } double weight(double y) override { // Implementation Note: Guard against messing up // `gsl_interp_accel' inside of Interpolator with a critical // section. #ifdef _OPENMP #pragma omp critical tabular_evaluate_weight #endif { // Implementation Note: We play it safe by using std::max() as // an interpolated function may overshoot to the negative // side. return std::max(interpolator->evaluate(y), 0.0); } } private: Interpolator* interpolator; }; // Tabular class HashedTabular : public Tabular { typedef Tabular super; public: void initialize(double y_optimum, double width_parameter, super::argument_const_iterator arguments_begin, super::argument_const_iterator arguments_end) override { super::initialize(y_optimum, width_parameter, arguments_begin, arguments_end); } double weight(double y) override { return super::weight(y); } private: std::unordered_map cache; }; // HashedTabular Tabular tabular; HashedTabular htabular; enblend-enfuse-4.2/doc/examples/Makefile.am0000644000175000017500000000016712637736744015640 00000000000000if DYNAMIC_EXPOSURE_WEIGHTS MAYBE_SHARE_ENFUSE = enfuse endif SUBDIRS = $(MAYBE_SHARE_ENFUSE) DIST_SUBDIRS = enfuse enblend-enfuse-4.2/doc/examples/Makefile.in0000644000175000017500000004600012676432431015632 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/examples DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/_ac_latex_test.m4 \ $(top_srcdir)/m4/ac_latex_class.m4 \ $(top_srcdir)/m4/ac_latex_package.m4 \ $(top_srcdir)/m4/ac_prog_ar.m4 \ $(top_srcdir)/m4/ac_prog_latex.m4 \ $(top_srcdir)/m4/ac_type_sig_atomic_t.m4 \ $(top_srcdir)/m4/ax_boost_base.m4 \ $(top_srcdir)/m4/ax_cxx_as_const.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/ax_openmp.m4 \ $(top_srcdir)/m4/ax_prog_perl_modules.m4 \ $(top_srcdir)/m4/ax_with_prog.m4 $(top_srcdir)/m4/lrint.m4 \ $(top_srcdir)/m4/lrintf.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONVERT = @CONVERT@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_IMPLEMENTATION = @DL_IMPLEMENTATION@ DOT = @DOT@ DVIPDF = @DVIPDF@ DVIPS = @DVIPS@ DYNAMIC_TEX_PREAMBLE = @DYNAMIC_TEX_PREAMBLE@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_LIBS = @EXTRA_LIBS@ GNUPLOT = @GNUPLOT@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_INLINE = @HAVE_INLINE@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LATEX = @LATEX@ LATEX2HTML = @LATEX2HTML@ LATEX2HTML_LIBDIR = @LATEX2HTML_LIBDIR@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ M4 = @M4@ MAKEINDEX = @MAKEINDEX@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ OPENEXR_LIBS = @OPENEXR_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SPLITHTML = @SPLITHTML@ STRIP = @STRIP@ SVGCONVERT = @SVGCONVERT@ TEXLOGANALYSER = @TEXLOGANALYSER@ VERSION = @VERSION@ VIGRAIMPEX_LIB = @VIGRAIMPEX_LIB@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ amsmath = @amsmath@ bindir = @bindir@ bold_extra = @bold_extra@ boretti_classesansparametre = @boretti_classesansparametre@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ color = @color@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enumitem = @enumitem@ exec_prefix = @exec_prefix@ float = @float@ footnote = @footnote@ graphicx = @graphicx@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hyperref = @hyperref@ hyphenat = @hyphenat@ ifpdf = @ifpdf@ includedir = @includedir@ index = @index@ infodir = @infodir@ install_sh = @install_sh@ latex = @latex@ latexsym = @latexsym@ libdir = @libdir@ libexecdir = @libexecdir@ listings = @listings@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ microtype = @microtype@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ ragged2e = @ragged2e@ refrep = @refrep@ report = @report@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shorttoc = @shorttoc@ srcdir = @srcdir@ suffix = @suffix@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ url = @url@ xstring = @xstring@ @DYNAMIC_EXPOSURE_WEIGHTS_TRUE@MAYBE_SHARE_ENFUSE = enfuse SUBDIRS = $(MAYBE_SHARE_ENFUSE) DIST_SUBDIRS = enfuse all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/examples/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic cscopelist-am ctags ctags-am \ distclean distclean-generic distclean-tags distdir dvi dvi-am \ html html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: enblend-enfuse-4.2/doc/enfuse-weighting-functions.tex0000644000175000017500000001423012667245443017754 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Weighting Functions]{\label{sec:weighting-functions}% \genidx[\rangebeginlocation]{weighting functions}% \genidx{exposure weighting!functions}% Weighting Functions} As has been noted in the introductory \flexipageref*{Overview}{sec:overview}, \App{} supports four different types of weighting. The following sections describe the concept of weighting and all weighting functions in detail. \section[Weighting Pixels]{\label{sec:weighting-pixels}% \genidx{weighting!general concept of}% Weighting Pixels} Image fusion maps each pixel~$P(i, x, y)$ of every input image~$i$ to a single pixel~$Q(x, y)$ in the output image: \[ P(i, x, y) \rightarrow Q(x, y), \] \noindent where $x$ runs from~1 to the width of the images, $y$ from~1 to the height, and $i$ from~1 to the number~$n$ of input images. \begin{equation} \label{equ:weight} w(P(1, x, y)) P(1, x, y) + \ldots + w(P(n, x, y)) P(n, x, y) \rightarrow Q(x, y), \end{equation} \noindent where \begin{itemize} \item each $w$ is non-negative to yield a physical intensity and \item the sum of all $w$ is 1 to leave the total intensity unchanged. \end{itemize} \noindent The pixel weights~$w$ themselves are weighted sums with the same constraints \begin{align*} w(P) = \; & w_{\mathrm{exp}} \; f_{\mathrm{exp}}(P) + \\ & w_{\mathrm{sat}} \; f_{\mathrm{sat}}(P) + \\ & w_{\mathrm{cont}} \; f_{\mathrm{cont}}(P, r_{\mathrm{cont}}) + \\ & w_{\mathrm{ent}} \; f_{\mathrm{ent}}(P, r_{\mathrm{ent}}). \end{align*} \noindent Here we have abbreviated $P(i, x, y)$ to $P$ for simplicity. The user defines the constants~$w_{\mathrm{exp}}$, $w_{\mathrm{sat}}$, $w_{\mathrm{cont}}$, and $w_{\mathrm{ent}}$ with the options~\option{--exposure-weight}, \option{--saturation-weight}, \option{--contrast-weight}, and \option{--entropy-weight} respectively. The functions~$f_{\mathrm{exp}}$, $f_{\mathrm{sat}}$, $f_{\mathrm{cont}}$, and $f_{\mathrm{ent}}$ along with the window sizes~$r_{\mathrm{cont}}$ and $r_{\mathrm{ent}}$ are explained in the next sections. \subsection[Weighted Average]{\label{sec:weighted-average}% \genidx{average!weighted}% \gensee{weighted average}{average, weighted}% Weighted Average} By default, \App{} uses a weighted average, where \emph{each} pixel contributes as much as its weight demands. Of course the weights can be extreme, favoring only a few pixels or even only one pixel in the input stack. Extremes are not typical, however. Equal weights are another extreme that turns \eqnref{equ:weight} into an arithmetic average. This is why we sometimes speak of the ``averaging property'' of this weighting algorithm, like smoothing out noise. \subsection[Disabling Averaging]{\label{sec:disabling-averaging}% \genidx{average!disabling}% \gensee{disabling average}{average, disabling}% \optidx{--hard-mask}% Disabling Averaging: Option~\sample{--hard-mask}} The weighted average computation as described above has proven to be widely successful with the exception of one special case: focus stacking, where the averaging noticeably softens the final image. Use \sample{--hard-mask} to switch \App{} into a different weighting mode, where the pixel with the highest weight wins, this is, gets weight~one, and all other pixels get the weight of zero. With option~\option{--hard-mask} \eqnref{equ:weight} becomes \[ % equ:weight-hard-mask P(i, x, y) \rightarrow Q(x, y), \] where \[ w(P(i, x, y)) \geq w(P(j, x, y)) \quad \mbox{for all}\quad 1 \leq j \leq n. \] \noindent Note that this ``averaging'' scheme lacks the nice noise-reduction property of the weighted average~\eqnref{equ:weight}, because only a single input pixel contributes to the output. \subsection[Single Criterion Fusing]{\label{sec:single-criterion-fusing}% \genidx{fusing!single criterion}% \gensee{single criterion fusing}{fusing, single criterion}% Single Criterion Fusing} \App{} allows the user to weight each pixel of an input image by up to four different criteria (see e.g.\ \chapterName~\fullref{sec:overview}). However, it does not force the user to do so. For some applications and more often simply to gain further insight into the weighting and fusing process, looking at only a single criterion is the preferred way to work. \genidx{criteria!active}% \gensee{active criteria}{criteria, active}% The version of \App{} for which this documentation was prepared, uses the default weights as stated in \tableName~\ref{tab:default-weights}. Notice that by default \emph{more than one} weight is larger than zero, which means they are \emph{active}. \begin{table} \centering \begin{tabular}{lc} \hline \multicolumn{1}{c|}{Criterion} & Default Weight \\ \hline\extraheadingsep Exposure & \val{val:default-weight-exposure} \\ Saturation & \val{val:default-weight-saturation} \\ Local Contrast & \val{val:default-weight-contrast} \\ Local Entropy & \val{val:default-weight-entropy} \end{tabular} \caption[Default weights]{\label{tab:default-weights}% \genidx{weights!default}% \gensee{default weights}{weights, default}% \App{}'s default weights as compiled into \app.} \end{table} To disable a particular criterion set its weight to zero as for example \begin{terminal} \$ \app{} \bslash \\ ~~~~--exposure-weight=1 --saturation-weight=0 \bslash \\ ~~~~--contrast-weight=0 --entropy-weight=0 \bslash \\ ~~~~image\_[1-3].png \end{terminal} instructs \App{} to consider only the exposure weight. Combine this with option~\option{--save-masks} and it will become clearer how \App{} computes the exposure weight for the set of images. \genidx{criteria!overpowering one another}% \gensee{overpowering criteria}{criteria, overpowering}% Another problem that can be inspected by fusing with just a single active criterion and saving the masks is if the weights of one criterion completely overpower all others. \input{enfuse-exposure-weighting} \input{enfuse-saturation-weighting} \input{enfuse-local-contrast-weighting} \input{enfuse-local-entropy-weighting} \genidx[\rangeendlocation]{weighting functions} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/sharp-edge.data0000644000175000017500000000017012541464343014615 00000000000000 0 0 200 0 0 0 225 0 0 0 0 255 0 0 0 215 0 0 0 0 200 0 0 0 0 enblend-enfuse-4.2/doc/entropy.gp0000644000175000017500000000044012566032753013776 00000000000000# Plot entropy with respect to base 2 _Base = 2.0 lb(x) = log(x) / log(_Base) Entropy(x) = -x * lb(x) - (1.0 - x) * lb(1.0 - x) set samples 1023 set xlabel "$p$" set xtics 0.2 set ylabel "$H_2(p)$" set ytics 0.2 unset key load DATA_DIR . "/colors.gp" plot [p = 0:1] Entropy(p) enblend-enfuse-4.2/doc/enfuse.tex0000644000175000017500000000215712676175553013774 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \RequirePackage{fixltx2e} \input{dynamic-preamble} \ifreferencemanual \documentclass[\documentclassoptions]{refrep} \else \documentclass[\documentclassoptions]{report} \fi \input{static-preamble} \input{enfuse-variables} \input{enfuse-version} \newif\ifenfuse\enfusetrue \newif\ifenblend\enblendfalse \newcommand*{\App}{\application{Enfuse}} \newcommand*{\app}{enfuse} \newcommand*{\appcmd}{\command{enfuse}} \newcommand*{\appdoes}{fuse} \newcommand*{\appdid}{fused} \newcommand*{\OtherApp}{\application{Enblend}} \newcommand*{\otherapp}{enblend} \newcommand*{\otherappcmd}{\command{enblend}} \finishdynamicpreamble \begin{document} \input{enfuse-title} \input{lead-in} \include{enfuse-overview} \include{common-known-limitations} \include{common-workflow} \include{enfuse-invocation} \include{enfuse-weighting-functions} \include{common-color-spaces} \include{common-understanding-masks} \include{enfuse-applications} \input{lead-out} \end{document} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enfuse-invocation.tex0000644000175000017500000000225412667236617016140 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Invocation]{\label{sec:invocation}% \genidx[\rangebeginlocation]{invocation}% \genidx{command-line}% Invocation} %HEVEA\cutdef{section} \noindent Fuse the sequence of images \metavar{INPUT}\dots{} into a single \metavar{IMAGE}. \smallskip \code{\app} \optional{\metavar{OPTIONS}} \optional{\option{--output=}\metavar{IMAGE}} \metavar{INPUT}\dots \smallskip \genidx{filename!literal}% \gensee{literal filename}{filename, literal}% \genidx{file!response}% \gensee{response file}{file, response}% \noindent \metavar{INPUT} images are either specified literally or via so-called response files (see \sectionName~\ref{sec:response-files}). The latter are an alternative to specifying image filenames on the command line. If omitted, the name of the output \metavar{IMAGE} defaults to \filename{\val{val:default-output-filename}}. \input{enfuse-image-requirements} \input{enfuse-options} \input{common-option-delimiters} \input{common-response-files} \input{common-layer-selection} \genidx[\rangeendlocation]{invocation} %HEVEA\cutend %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enblend-options.tex0000644000175000017500000000223012667236617015576 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \section[Command-Line Options]{\label{sec:options}% \genidx[\rangebeginlocation]{options}% Command-Line Options} In this section we group the options as the command-line help \begin{terminal} \$ \app{} --help \end{terminal} does and sort them alphabetically within their groups. For an alphabetic list of \emph{all} options consult the \flexipageref{Option Index}{sec:option-index}. \appcmd{} accepts arguments to any option in uppercase as well as in lowercase letters. For example, \sample{deflate}, \sample{Deflate} and \sample{DEFLATE} as arguments to the \option{--compression}~option described below all instruct \appcmd{} to use the \propername{Deflate} compression scheme. This manual denotes all arguments in lowercase for consistency. \input{common-common-options} \input{common-advanced-options} \input{enblend-mask-generation-options} \input{common-expert-options} \input{enblend-expert-mask-generation-options} \input{common-information-options} \input{enblend-flow-charts} \genidx[\rangeendlocation]{options} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/internal-optimizer-chain.dot0000644000175000017500000000264412562317012017370 00000000000000digraph InternalOptimizerChain { graph [uml_activity_graph] node [uml_activity] _start [uml_start] minimizer_prerequisites_fork [uml_fork] vectorize_mask [label = "Vectorize seam-line of mask;\n--mask-vectorize"] difference_image [label = "Compute difference image;\n--image-difference"] minimizer_prerequisites_join [uml_join] run_minimizer [label = "Path-length/difference minimizer;\n--optimizer-weights\n--anneal"] dijkstra_search [label = "Dijkstra minimizer;\n--dijkstra"] devectorize_seam_line [label = "Convert optimized\nseam-line to mask"] _finish [uml_finish] node [uml_note] run_minimizer_note [label = "Simulated-Annealing\nminimizer"] dijkstra_search_note [label = "Dijkstra's \"shortest-path\"\nalgorithm"] {rank = same; run_minimizer; run_minimizer_note} {rank = same; dijkstra_search; dijkstra_search_note} edge [uml_edge] _start -> minimizer_prerequisites_fork minimizer_prerequisites_fork -> vectorize_mask minimizer_prerequisites_fork -> difference_image difference_image -> minimizer_prerequisites_join vectorize_mask -> minimizer_prerequisites_join minimizer_prerequisites_join -> run_minimizer run_minimizer -> dijkstra_search dijkstra_search -> devectorize_seam_line devectorize_seam_line -> _finish edge [uml_note_edge] run_minimizer -> run_minimizer_note dijkstra_search -> dijkstra_search_note } enblend-enfuse-4.2/doc/common-color-spaces.tex0000644000175000017500000004472212676175561016372 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Color Spaces\commonpart]{\label{sec:color-spaces}% \genidx[\rangebeginlocation]{colorspace}% \genidx{color profile}% Color Spaces And Color Profiles\commonpart} \genidx{profile!ICC@\acronym{ICC}}% \gensee{ICC@\acronym{ICC} profile}{profile, \acronym{ICC}}% This chapter explains the connection of pixel data types, \uref{\wikipediaiccprofile}{\acronym{ICC}}-color profiles, blend color spaces in \App{} or \OtherApp. \genidx{pixels!blending}% \gensee{blending pixels}{pixels, blending}% \genidx{pixels!fusing}% \gensee{fusing pixels}{pixels, fusing}% Here, we collectively speak of blending and do not distinguish fusing, for the basic operations are the same. Furthermore, we assume the multi-resolution spline algorithm has calculated a set of weights~$w_i$ for $i = 1, 2, \dots$~and $\sum w_i = 1$ for each pixel that must be blended from the participating input pixels~$P_i, i = 1, 2, \dots$. \genidx{weighting factor}% \genidx{luminance}% In the simplest, non-trivial case we have to blend a pair of grayscale input pixels. Given their luminances~$L_1$, $L_2$ and their weighting factor~$0 \leq w \leq 1$, what luminance~$L$ is their ``weighted average''? This is the heart of \App's and \OtherApp's pyramidal blending operations! We are in particular interested in a weighted average that appears \emph{visually} correct, this is, our eyes and brains consider $L$ convincing or at the very least credible. \begin{geeknote} \noindent Note that \App{} and \OtherApp{} face different obstacles in their respective domains of use. \begin{description} \item[\application{Enblend}]\itemend The overlapping areas usually are \emph{well matched} both geometrically and photometrically. The differences of the pixels that must be blended are small. \item[\application{Enfuse} (using a Soft Mask\footnote{Fusing with a Hard Mask is different, because exactly one weight factor is unity and all the others are zero. There is nothing to blend -- just to copy.})]\itemend The input images \emph{greatly differ} in exposure, saturation, or contrast. This is exactly why we want to fuse them. Thus, the luminance, saturation, and hue differences to be handled by \application{Enfuse} are generally quite high. \end{description} \end{geeknote} The details of blending pixels and in particular color pixels is quite intricate, which is why we start this chapter with a mathematical introduction. \section[Mathematical Preliminaries]{\label{sec:mathematical-preliminaries}% \genidx{color profiles!math}% Mathematical Preliminaries} \genidx{luminance interval}% \genidx{luminance interval!normalized}% Let us first address grayscale images because they only require us to talk about luminances. For a linear representation of luminances, we just blend for a given $t$ with \begin{equation}\label{equ:trivial-luminance-blend} L = t L_1 + (1 - t) L_2 \quad \mbox{with} \quad 0 \leq t \leq 1, \end{equation} where the luminances~$L_i, i = 1, 2,$ range from zero to their data-type dependent maximum value~$L_{\mathrm{max}}$, thereby defining a ``luminance interval''. We can always map this interval to $(0, 1)$ by dividing the luminances by the maximum, which is why we call the latter \emph{``normalized luminance interval''}: \begin{equation}\label{equ:luminance-normalization} (0, L_{\mathrm{max}}) \rightarrow (0, 1) \end{equation} Obviously, \begin{equation}\label{equ:normalized-luminance} 0 \leq \bar{L} \leq 1 \end{equation} holds for all values~$\bar{L} := L / L_{\mathrm{max}}$ in the normalized luminance interval. \genidx{luminance interval!normalized}% Sometimes images are gamma-encoded with exponent~$\gamma$ and the blended luminance becomes \begin{equation}\label{equ:gamma-luminance-blend} L' = \left(t L_1^{1/\gamma} + (1 - t) L_2^{1/\gamma}\right)^\gamma, \end{equation} \genidx{Brasseur@\propername{Brasseur, Eric}}% which couples $t$ and $L'$ in a non-linear way. See also \propername{Eric Brasseur's} explanation of the \uref{\ericbrasseurgamma}{gamma error in picture scaling}. \begin{geeknote} \genidx{Lindbloom@\propername{Lindbloom, Bruce}}% Typical gamma values are $\gamma = 2.2$ for \acronym{sRGB} and \acronym{AdobeRGB}, 1.8 for \acronym{AppleRGB}, and \acronym{ProPhotoRGB}, 1.0 for Linear Rec709 \acronym{RGB} and any others with ``linear'' in their names. For an extensive overview check out \propername{Bruce Lindbloom's} \uref{\brucelindbloomworkingspaceinfo}{Information on Working Color Spaces.} \end{geeknote} The usual color-input images fed into \App{} are \acronym{RGB}-encoded, which means each pixel comes as a triple of values~$\transpose{(r, g, b)}$ that represent the red, green, and~blue parts. We apply the normalization~\eqnref{equ:luminance-normalization} to each of the three primary colors and arrive at an \emph{``\acronym{RGB}-cube''} with unit edge length. The vectors of primary colors span the cube \[ \vec{r} = \left(\begin{array}{c}1\\ 0\\ 0\end{array}\right),\quad \vec{g} = \left(\begin{array}{c}0\\ 1\\ 0\end{array}\right)\quad \mbox{and}\quad \vec{b} = \left(\begin{array}{c}0\\ 0\\ 1\end{array}\right). \] For each point inside -- familiarly called pixel -- the generalization of \eqnref{equ:normalized-luminance} holds \begin{equation}\label{equ:rgb-cube} \left(\begin{array}{c}0\\ 0\\ 0\end{array}\right) \leq \left(\begin{array}{c}r\\ g\\ b\end{array}\right) \leq \left(\begin{array}{c}1\\ 1\\ 1\end{array}\right). \end{equation} Blending the pixels of \emph{color} images is more complicated than blending plain luminances. Although we can write down the na\"ive blending equation, \eqnref{equ:trivial-luminance-blend}, again for \acronym{RGB}-coded pixels \[ P_1 := \left(\begin{array}{c}r_1\\ g_1\\ b_1\end{array}\right) \quad \mbox{and}\quad P_2 := \left(\begin{array}{c}r_2\\ g_2\\ b_2\end{array}\right) \] and trivially arrive at \begin{equation}\label{equ:trivial-rgb-blend} P := \left(\begin{array}{c}r\\ g\\ b\end{array}\right) = t \left(\begin{array}{c}r_1\\ g_1\\ b_1\end{array}\right) + (1 - t) \left(\begin{array}{c}r_2\\ g_2\\ b_2\end{array}\right) \quad \mbox{with} \quad 0 \leq t \leq 1, \end{equation} but this means \begin{compactitemize} \item we implicitly treat the color components $r_i, g_i, b_i$ as \emph{separate} luminances, which they are not and moreover \item we neglect the visual aspects, namely luminance, saturation, and~hue of the blended color pixel~$P$. \end{compactitemize} \section[Floating-Point Images]{\label{sec:floating-point-images}% \genidx{image!floating-point}% \gensee{floating-point image}{image, floating-point}% Floating-Point Images} \genidx{transform!floating-point images}% \genidx{image!\acronym{EXR}}% \gensee{EXR@\acronym{EXR} image}{image, \acronym{EXR}}% \genidx{image!floating-point \acronym{TIFF}}% \gensee{floating-point \acronym{TIFF} image}{image, floating-point \acronym{TIFF}}% \genidx{image!floating-point \acronym{VIFF}}% \gensee{floating-point \acronym{VIFF} image}{image, floating-point \acronym{VIFF}}% \gensee{VIFF@\acronym{VIFF} floating-point image}{image, floating-point \acronym{VIFF}}% \genidx{transform!log}% \gensee{log-transform}{transform, log}% Floating-point images (\acronym{EXR}, floating-point \acronym{TIFF}, or \acronym{VIFF}) get a special treatment. Their values~$L$ are first converted by the \LogTransform-transform. \begin{equation}\label{equ:log-transform} \mbox{Log}(L) := \left\{ \begin{array}{ll} 1 + \log(1 + L) & \quad \mbox{for } L \geq 0 \mbox{ and} \\ 1 / (1 - L) & \quad \mbox{otherwise,} \end{array} \right. \end{equation} \noindent which is undone by the inverse transform after blending. Here, $\log(x)$ with a lower-case initial denotes the natural logarithmic function (i.e.\ to base~$e$). \figureName~\ref{fig:log-transform} shows the forward transform in the range from $-20$ to~100. Around $L = 0$ function~$\mbox{Log}(L)$ has the series expansion \[ \mbox{Log}(L) = 1 + L + \frac{L^2}{2} + O(L^3), \mbox{for } 0 \leq L < 1. \] \begin{figure} \centering \includeimage{log-transform} \caption[\LogTransform-transform]% {\label{fig:log-transform}\genidx{transform!log}% Forward \LogTransform-transform shown for the range of $-20 \leq L \leq 100$. The domain of $\LogTransform(L)$ is the whole real axis.} \end{figure} This transform serves two purposes: \begin{itemize} \item During blending, even completely non-negative images can result in negative pixels. A \LogTransform-transform followed by the inverse guarantees all-positive output. \item For \acronym{HDR}~data, the \LogTransform-transform puts the samples closer to a perceptual space making the blending a little more pleasing. \end{itemize} In the current version of \App{} and \OtherApp{} it is \emph{strongly recommended} to use blending inside the \acronym{RGB}-cube whenever the input data is in floating-point format; this is the default, too. \section[Color Profiles]{\label{sec:color-profiles}% \genidx{color profile}% Color Profiles} \genidx{black-point}% \gensee{ICC@\acronym{ICC} profile black-point}{black-point}% \genidx{white-point}% \gensee{ICC@\acronym{ICC} profile white-point}{white-point}% \acronym{ICC}-color profiles completely absorb gamma encodings~\eqnref{equ:gamma-luminance-blend} and \acronym{ICC}~profile aware software like \App{} and \OtherApp{} decode and encode images automatically respecting the gamma curves. Moreover color profiles define what is the darkest representable black, so called black-point \[ L = 0 \quad \mbox{and}\quad \transpose{(r, g, b)} = \transpose{(0, 0, 0)} \] and analogously what is the purest and brightest white, the white-point \[ L = 1 \quad \mbox{and}\quad \transpose{(r, g, b)} = \transpose{(1, 1, 1)}. \] \noindent By default, \App{} and \OtherApp{} expect that either \begin{compactenumerate} \item\label{enum:no-profile} no input image has a color profile or \item\label{enum:same-profile} all images come with the \emph{same} \acronym{ICC}~profile. \end{compactenumerate} \genidx{image!black-and-white}% \gensee{black-and-white image}{image, black-and-white}% Even black-and-white images benefit from having attached appropriate profiles! \genidx{color cube!\acronym{RGB}}% \gensee{RGB@\acronym{RGB} color cube}{color cube, \acronym{RGB}}% \genidx{color cube!\acronym{sRGB}}% \gensee{sRGB@\acronym{sRGB} color cube}{color cube, \acronym{sRGB}}% In Case~\ref{enum:no-profile}.\ the applications blend grayscale images in the normalized luminance interval and color images inside the \acronym{sRGB}-cube. To override the default \acronym{sRGB}-profile select the desired profile with option~\flexipageref{\option{--fallback\hyp profile}}{opt:fallback-profile}. In Case~\ref{enum:same-profile}.\ the images first are by default transformed to \uref{\wikipediaciecam}{\acronym{CIELUV}} color space -- respecting the input color profile -- then they are blended or fused, and finally the data get transformed back to \acronym{RGB} color space defined by the profile of the input images. Consequently, the input profile is assigned to the output image. Enforce a different blending color space than \acronym{CIELUV} with option~\flexipageref{\option{--blend-colorspace}}{opt:blend-colorspace}. Mixing different \acronym{ICC}~profiles or alternating between images with profiles and without them generates warnings as it generally leads to unpredictable results. Floating-Point images are an exception to the above rules. They are \emph{always} blended in the \acronym{RGB} cube by default. The next section describes their treatment in detail. \section[Blending Color Spaces]{\label{sec:blending-color-spaces}% \genidx{colorspace!for blending and fusing}% \gensee{blending color space}{colorspace, for blending and fusing}% Blending Color Spaces} \App{} and \OtherApp{} offer to work inside the \acronym{RGB}-cube~\eqnref{equ:rgb-cube} or in several perceptually uniform color spaces. To override the default select a particular blending color space with option~\flexipageref{\option{--blend-colorspace}}{opt:blend-colorspace}. Here are the four available color spaces. \begin{description} \genidx{color cube!\acronym{RGB}}% \gensee{RGB@\acronym{RGB} color cube}{color cube, \acronym{RGB}}% \item[Identity Space / \acronym{RGB}-Color Cube]\itemend Calculate the blended pixel inside the luminance interval \eqnref{equ:trivial-luminance-blend} for grayscale images and inside the \acronym{RGB}-color cube as given in \eqnref{equ:trivial-rgb-blend}. This is the fastest color space to do computations within, i.e.\ it consumes by far the least computing power, because no transform to or from any of the perceptually uniform color spaces is done. \genidx{colorspace!\acronym{L*a*b*}}% \gensee{L*a*b*@\acronym{L*a*b*} colorspace}{colorspace, \acronym{L*a*b*}}% \genidx{white-point!\acronym{D50}}% \gensee{D50@\acronym{D50} white-point}{white-point, \acronym{D50}}% \item[\urlmark{\wikipedialabcolorspace}{\acronym{L*a*b*}}]\itemend\urltext Represent each pixel as lightness~$L\raisedasterisk$, red-green difference~$a\raisedasterisk$, and yellow-blue difference~$b\raisedasterisk$. The \acronym{L*a*b*} color space encompasses all perceivable colors. It is completely independent of any device characteristics, approximates human vision, and is perceptually uniform. \App{} uses perceptual rendering intent and either the input profile's white-point or, if the \acronym{ICC}-profile lacks the \code{cms\shyp Sig\shyp Media\shyp White\shyp Point\shyp Tag}, fall back to the \acronym{D50} white-point (see, e.g.\ \uref{\wikipediastandardilluminant}{Standard illuminant}). The conversions from and to \acronym{L*a*b*} are moderately fast to compute; \acronym{L*a*b*} mode is two to three times slower than working within the \acronym{RGB}-color cube. \genidx{colorspace!\acronym{CIEL*u*v*}}% \gensee{CIEL*u*v*@\acronym{CIEL*u*v*} colorspace}{colorspace, \acronym{CIEL*u*v*}}% \item[\urlmark{\wikipediacieluvcolorspace}{\acronym{CIEL*u*v*}}]\itemend\urltext Represent each pixel as lightness~$L\raisedasterisk$ and two color differences~$u\raisedasterisk$ and $v\raisedasterisk$. Formulas of each are too complicated to show them here. The \acronym{L*u*v*} tries to be perceptually uniform in lightness as well as in color. The applications use the same rendering intent and white-point as with \acronym{L*a*b*}. The conversions from and to \acronym{L*u*v*} are almost as fast to compute as \acronym{L*a*b*}. \genidx{colorspace!\acronym{CIECAM02}}% \gensee{CIECAM02@\acronym{CIECAM02} colorspace}{colorspace, \acronym{CIECAM02}}% \genidx{rendering intent!perceptual}% \gensee{perceptual rendering intent}{rendering intent}% \genidx{white-point!\acronym{D50}}% \gensee{D50@\acronym{D50} white-point}{white-point, \acronym{D50}}% \item[\urlmark{\wikipediaciecam}{\acronym{CIECAM02}}]\itemend\urltext Represent each pixel as lightness~$J$, chroma~$C$ (``colorfulness''), and hue angle~$h$. \begin{geeknote} Internally, the polar coordinates $(C, h)$ are translated to \propername{Cartesian} coordinates for the pyramids. \end{geeknote} The transformations to \acronym{CIECAM02} color space and back use perceptual rendering intent, the \acronym{D50} white point (see, e.g.\ \uref{\wikipediastandardilluminant}{Standard illuminant}), 500\dmn{lumen} surrounding light (``average'' in \acronym{CIECAM02} parlance), and assume complete adaption. Both \acronym{CIELUV} and \acronym{CIELAB} only model the color information generated for small and isolated color samples. They cannot model the contextual effects of color perception. However, \acronym{CIECAM02} can represent luminance adaptation, chromatic contrast and chromatic assimilation that arise in real world viewing conditions with heterogeneous, strongly contrasted, or three dimensional color sources. Computationally, \acronym{CIECAM02} is the most expensive blend color space. If an appreciable number of pixels need additional refinement steps the speed of the transformation further drops. Expect \acronym{CIECAM02} mode to be 8--800 times slower than blending within the \acronym{RGB}-color cube. \end{description} \noindent Surprisingly often blending ``inside the \acronym{RGB}-cube'' works, although perceptually uniform color spaces, which represent luminance, saturation, and hue are preferable for blending and fusing operations. \section[Practical Considerations]{\label{sec:practical-considerations}% \genidx{colorspace!practical considerations}% Practical Considerations} \begin{itemize} \item For small projects stick with the default blend colorspaces. \item For large projects switch on blending in the \acronym{RGB} color cube to speed up the assembly of the images. When satisfied with all other parameters use one of the computationally more expensive, but perceptually uniform color spaces. \item Banding is best fought by input images with a high bit depth (\mbox{$\geq 16$ bits} per channel). A cheap and mostly vain trick is to force a large output bit depth with option~\flexipageref{\option{--depth}}{opt:depth}. No blend color space can avoid banding if parts of the input images are almost ``monochrome''. \ifenblend \item \restrictednote{\application{Enblend} only.} No color space can fix a seam-line gone haywire! First re-run \application{Enblend} with \flexipageref{\sample{--visualize}}{opt:visualize} to inspect the seam-lines, then try one or more of the following \begin{itemize} \item Reorder the input images. \item Force blending with the full-resolution masks, using option~\flexipageref{\option{--fine\hyp mask}}{opt:fine-mask}. \item Generate the initial seam with the simpler and more robust nearest\hyp feature transform (\acronym{NFT}) by employing option~\flexipageref{\option{--pri\shyp ma\shyp ry\hyp seam\hyp ge\shyp ne\shyp ra\shyp tor=nearest-feature-transform}}{opt:primary-seam-generator}. See also \chapterName~\fullref{sec:seam-generators}. \item Disable the seam-line optimizer with \flexipageref{\sample{--no-optimize}}{opt:optimize}. \end{itemize} \fi \ifenfuse \item \restrictednote{\application{Enfuse} only.} No color space can fix blown highlights when fusing by exposure-weight; use \flexipageref{\sample{--exposure-cutoff}}{opt:exposure-cutoff} for this purpose and check whether saturation weight is zero. \fi \end{itemize} \genidx[\rangeendlocation]{colorspace} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/cleantex0000755000175000017500000000404712602767761013513 00000000000000#! /usr/bin/env perl # This file is part of Enblend. # Licence details can be found in the file COPYING. # name: cleantex # synopsis: Remove (La)TeX constructs from a file, but in contrast # to detex(1) try to recover as much as possible. # author: Dr. Christoph L. Spiel # perl version: 5.20.2 use strict; use warnings; use English; use File::Basename (); use FindBin qw($Bin); use Getopt::Long; use Readonly; use lib $Bin; use OpenFile; Readonly my $COMMAND_NAME => File::Basename::basename($PROGRAM_NAME); sub replace { my ($options, $filename) = @_; my $file = OpenFile::open_file($filename); while (my $line = readline $file) { chomp $line; # Tilde chars just represent spaces $line =~ s/~/ /g; # TeX inline math demimiters go away $line =~ s/\$//g; # Dutifully applied quotation marks become the profane # version. If we are sure to write out Unicode, we could use # guillemets. $line =~ s/``/"/g; $line =~ s/''/"/g; # Remove macro call remembering that we had to double backslashes $line =~ s/\\\\[A-Za-z]*//g; # Remove delimiters $line =~ s/[{}]//g; print "$line\n"; } $file->close; } sub show_help { my $options = shift; print < sub {show_help($options)}) or warn "$COMMAND_NAME: problems while parsing options\n"; } sub main { my $options = {}; get_options($options); for my $filename (@ARGV) { replace($options, $filename); } return 0; } main(); enblend-enfuse-4.2/doc/common-notation.tex0000644000175000017500000000616012676423754015625 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \ifhevea \let\thesectionoriginal\thesection \renewcommand{\thesection}{Frontmatter \Alph{section}} \section{\label{sec:notation}% \genidx{notation}% \gensee{typographic conventions}{notation}% \gensee{conventions!typographic}{notation}% Notation} \let\thesection\thesectionoriginal \else \section*{\label{sec:notation}% \genidx{notation}% \gensee{typographic conventions}{notation}% \gensee{conventions!typographic}{notation}% Notation} \fi This manual uses some typographic conventions to clarify the subject. The markup of the ready-to-print version differs from the web markup. \begin{center} \begin{tabular}{p{.18\linewidth}p{.39\linewidth}l} \hline \multicolumn{1}{c|}{Category} & \multicolumn{1}{c|}{Description} & \multicolumn{1}{c}{Examples} \\ \hline\extraheadingsep Acronym & Common acronym & \acronym{sRGB}, \acronym{OpenMP} \\ Application & \acronym{GUI} or \acronym{CLI} application & \application{Hugin}, \App \\ Command & Name of a binary in the running text & \command{convert}, \appcmd \\ Common part & Chapter, section, or any other part that appears in both manuals & Response Files\commonpart \\ Default & Value as compiled into the \appcmd{} binary that belongs to this documentation & \indicatesourcevalue{1}, \indicatesourcevalue{\filename{a.tif}} \\ Environment variable & Variable passed to \app{} by the operating system & \envvar{PATH}, \envvar{TMPDIR} \\ Filename & Name of a file in the filesystem & \filename{a.tif} \\ Filename extension & Name of a filename extension with or without dots & \filename{.png}, \filename{tiff}\\ Fix me! & Section that needs extending or at least some improvement & \fixme{Explain} \\ Literal text & Text that (only) makes sense when typed in exactly as shown & \code{uint16} \\ Option & Command-line option given to \app & \option{--verbose} \\ Optional part & Optional part of a syntax description in square brackets & \option{--verbose}~\optional{=\metavar{LEVEL}} \\ Placehoder & Meta-syntactic variable that stands in for the actual text & \metavar{ICC-PROFILE} \\ Proper name & Name of a person or algorithm & \propername{Dijkstra} \\ Restricted note & Annotation that applies only to a particular program, configuration,~or operating system & \restrictednote{\App.} \\ Sample & Literal text in quotes & \sample{\%} or \sample{--help} \\ Side note & Non-essential or ``geeky'' material & {\geekytext Gory details} \\ White space & Indispensable white space & \code{r}\textvisiblespace\code{g}\textvisiblespace\code{b} \\ \end{tabular} \end{center} \ifhevea\relax\else If we must break an identifier like for example \option{--show-soft\shyp ware-com\shyp po\shyp nents} or \envvar{EN\shyp BLEND\_OPEN\shyp CL\_PATH} at the end of a line, we indicate the additional character which does not occur when the identifier is written as one word with a \sample{\signalinghyphenchar}-character. \fi %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enfuse-title.tex0000644000175000017500000000253712676175540015111 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \begin{titlepage} \renewcommand{\thefootnote}{\fnsymbol{footnote}} \author{Andrew~Mihal\footnote{Original author} \and Christoph~Spiel} \title{Combining Multiple Images\\ with\\ Enfuse \val*{val:VERSION}} \date{\val*{val:UPDATED}} \maketitle \end{titlepage} \pagenumbering{roman} \vspace*{\fill} \ifhevea \relax \else \begin{center}\strong{Abstract}\end{center} \fi \label{sec:abstract}\noindent This manual is for \App{} version~\val{val:VERSION}, a tool to merge different exposures of the same scene to produce an image that looks much like a tone-mapped image. \vspace*{\fill} \begin{flushleft} Copyright \copyright{} 2004--2009 \propername{Andrew Mihal}. \\ Copyright \copyright{} 2009--2016 \propername{Christoph Spiel}. \end{flushleft} \begin{quotation} \noindent Permission is granted to copy, distribute and/or modify this document under the terms of the \acronym{GNU} Free Documentation License, Version~1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. A copy of the license is included in the section entitled ``\acronym{GNU} Free Documentation License''. \end{quotation} \cleardoublepage{} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/common-understanding-masks.tex0000644000175000017500000001421012676175561017746 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \chapter[Understanding Masks\commonpart]{\label{sec:understanding-masks}% \genidx{mask}% \genidx[\rangebeginlocation]{understanding masks}% Understanding Masks\commonpart} \genidx{mask!binary}% \gensee{binary mask}{mask, binary}% \genidx{mask!weight}% A binary mask indicates for every pixel of an image if this pixel must be considered in further processing, or ignored. For a weight mask, the value of the mask determines how much the pixel contributes, zero again meaning ``no contribution''. Masks arise in two places: as part of the input files and as separate files, showing the actual pixel weights prior to image blending or fusion. We shall explore both occurrences in the next sections. \section[Masks In Input Files]{\label{sec:masks-in-input-files}% \genidx{mask!input files}% \gensee{input mask}{mask, input files}% Masks In Input Files} Each of the input files for \App{} and \OtherApp{} can contain its own mask. Both applications interpret them as binary masks no matter how many bits per image pixel they contain. Use \application{ImageMagick}'s \prgidx{identify \textrm{(ImageMagick)}}\command{identify} (see \exampleName~\ref{ex:using-identify}) or, for \acronym{TIFF} files only, \prgidx{tiffinfo \textrm{(libtiff)}}\command{tiff\/info} (see \exampleName~\ref{ex:using-tiffinfo}) to inquire quickly whether a file contains a mask. \appendixName~\fullref{sec:helpful-programs} shows where to find these programs on the web. \begin{exemplar} \begin{terminal} \$ identify -version \\ Version: ImageMagick 6.7.7-10 2014-03-08 Q16 http://www.imagemagick.org \\ Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC \\ Features: OpenMP \\ ~ \\ \$ identify -format "\%f \%m \%wx\%h \%r \%q-bit" image-0000.tif \\ image-0000.tif TIFF 917x1187 DirectClass sRGB Matte 16-bit \\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\caret\caret\caret\caret\caret \\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\textit{mask} \end{terminal} \caption[Using \command{identify}.]% {\label{ex:using-identify}% Using \command{identify} to find out about the mask in \filename{image-0000.tif}. \sample{Matte} indicates the existence of a mask.} \end{exemplar} \begin{exemplar} \begin{terminal} \$ tiffinfo \\ LIBTIFF, Version 4.0.2 \\ Copyright (c) 1988-1996 Sam Leffler \\ Copyright (c) 1991-1996 Silicon Graphics, Inc. \\ \dots \\ ~ \\ \$ tiffinfo image-0000.tif \\ TIFF Directory at off set 0x3a8182 (3834242) \\ ~~Subfile Type: (0 = 0x0) \\ ~~Image Width: 917 Image Length: 1187 \\ ~~Resolution: 150, 150 pixels/inch \\ ~~Position: 0, 0 \\ ~~Bits/Sample: 8 \\ ~~Sample Format: unsigned integer \\ ~~Compression Scheme: PackBits \\ ~~Photometric Interpretation: RGB color \\ ~~Extra Samples: 1~~~~~~~~~~~~~~~\textit{mask} \\ ~~Orientation: row 0 top, col 0 lhs \\ ~~Samples/Pixel: 4~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\textit{R, G, B, and mask} \\ ~~Rows/Strip: 285 \\ ~~Planar Configuration: single image plane \\ ~~ImageFullWidth: 3000 \\ ~~ImageFullLength: 1187 \end{terminal} \caption[Using \command{tiff\/info}.]% {\label{ex:using-tiffinfo}% Using \command{tiff\/info} to find out about the mask in \filename{image-0000.tif}. Here the line \sample{Extra Samples} indicates one extra sample per pixel, which is interpreted as an unassociated alpha-channel; \App{} and \OtherApp{} interpret this as mask. The second hint \command{tiff\/info} gives is in \sample{Samples/Pixel}, where -- for a \acronym{RGB}-image -- the $4 = 3 + 1$ tells about the extra channel.} \end{exemplar} \genidx{matte}% \genidx{extra samples}% \genidx{alpha}% The ``Matte'' part of the image class and the ``Extra Samples'' line tell us that the file features a mask. Also, many interactive image manipulation programs show the mask as a separate channel, sometimes called ``alpha''. There, the white (high mask value) parts of the mask enable pixels and black (low mask value) parts suppress them. The multitude of terms all describing the concept of a mask is confusing. \begin{description} \genidx{mask}% \item[Mask]\itemend A mask defines a selection of pixels. A value of zero represents an unselected pixel. The maximum value (``white'') represents a selected pixel and the values between zero and the maximum are partially selected pixels. See \uref{\gimpsavvy}{Gimp-Savy.} \genidx{channel!alpha}% \item[Alpha Channel]\itemend The alpha channel stores the transparency value for each pixel, typically in the range from zero to one. A value of zero means the pixel is completely transparent, thus does not contribute to the image. A value of one on the other hand means the pixel is completely opaque. \genidx{matte}% \item[Matte]\itemend The notion ``matte'' as used by \application{ImageMagick} refers to an inverted alpha channel, more precisely: $1 - \mbox{alpha}$. See \uref{\imagemagickorgusagechannelstrans}{\application{ImageMagick}} for further explanations. \end{description} \App{} and \OtherApp{} only consider pixels that have an associated mask value other than zero. If an input image does not have an alpha channel, \application{Enblend} warns and assumes a mask of all non-zero values, that is, it will use every pixel of the input image for fusion. \prgidx{nona \textrm{(Hugin)}}% Stitchers like \command{nona} add a mask to their output images. Sometimes it is helpful to manually modify a mask before fusion. For example to suppress unwanted objects (insects and cars come into mind) that moved across the scene during the exposures. If the masks of all input images are black at a certain position, the output image will have a hole in that position. \section[Weight Mask Files]{\label{sec:weight-mask-files}% \genidx{mask!weight}% \gensee{weight!mask}{mask, weight}% Weight Mask Files} \fixme{Show some weight masks and explain them.} \genidx[\rangeendlocation]{understanding masks} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/common-information-options.tex0000644000175000017500000001577312676423754020022 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \subsection[Information Options\commonpart]{\label{sec:information-options}% \genidx[\rangebeginlocation]{information options}% \genidx{options!information}% Information Options\commonpart} \begin{codelist} \label{opt:help}% \optidx[\defininglocation]{--help}% \shoptidx{-h}{--help}% \genidx{help}% \item[\itempar{-h \\ --help}]\itemend Print information on the command-line syntax and all available options, giving a boiled-down version of this manual. \label{opt:show-globbing-algorithms}% \optidx[\defininglocation]{--show-globbing-algorithms}% \genidx{algorithm!globbing}% \gensee{globbing algorithms}{algorithm, globbing}% \item[--show-globbing-algorithms]\itemend Show all globbing algorithms. Depending on the build-time configuration and the operating system the binary may support different globbing algorithms. See \sectionName~\fullref{sec:globbing-algorithms}. %% -- Commented out for Stable Branch 4.2 %% \label{opt:show-gpu-info}% %% \optidx[\defininglocation]{--show-gpu-info}% %% \genidx{GPU@\acronym{GPU}}% %% \genidx{OpenCL@\acronym{OpenCL}}% %% \genidx{GPU@\acronym{GPU}!information on}% %% \gensee{information!on \acronym{GPU}}{\acronym{GPU}, information}% %% \genidx{OpenCL@\acronym{OpenCL}!information on configuration}% %% \gensee{information!on \acronym{OpenCL} configuration}{\acronym{OpenCL}, information}% %% \item[--show-gpu-info \restrictednote{\acronym{OpenCL}-enabled versions only.}]\itemend %% Print a list of all available \acronym{GPU}~devices under \acronym{OpenCL}~control on all %% accessible platforms, the current preferences, and then exit; it is the same enumeration that %% \begin{literal} %% \app{} --verbose --version %% \end{literal} %% reveals. \exampleName~\ref{ex:opencl-config} shows a complete output. %% %% \begin{exemplar} %% \begin{maxipage} %% \begin{terminal} %% \$ \app{} --show-gpu-info \\ %% Available, OpenCL-compatible platform(s) and their device(s) \\ %% ~~- Platform \#1:~Advanced Micro Devices, Inc., \\ %% ~~~~~~~~~~~~~~~~~AMD Accelerated Parallel Processing, \\ %% ~~~~~~~~~~~~~~~~~OpenCL 1.2 AMD-APP (1526.3) \\ %% ~~~~* no GPU devices found on this platform \\ %% ~~- Platform \#2:~NVIDIA Corporation, \\ %% ~~~~~~~~~~~~~~~~~NVIDIA CUDA, \\ %% ~~~~~~~~~~~~~~~~~OpenCL 1.1 CUDA 6.5.51 \\ %% ~~~~* Device \#1:~max.~1024 work-items \\ %% ~~~~~~~~~~~~~~~~~1047872 KB global memory with 32 KB read/write cache \\ %% ~~~~~~~~~~~~~~~~~48 KB dedicated local memory \\ %% ~~~~~~~~~~~~~~~~~64 KB maximum constant memory \\ %% ~~~~~~~~~~~~~~~~~Extensions: \\ %% ~~~~~~~~~~~~~~~~~~~~~cl\_khr\_byte\_addressable\_store \\ %% ~~~~~~~~~~~~~~~~~~~~~cl\_khr\_fp64 \\ %% ~~~~~~~~~~~~~~~~~~~~~cl\_khr\_gl\_sharing \\ %% ~~~~~~~~~~~~~~~~~~~~~cl\_khr\_global\_int32\_base\_atomics \\ %% ~~~~~~~~~~~~~~~~~~~~~cl\_khr\_global\_int32\_extended\_atomics \\ %% ~~~~~~~~~~~~~~~~~~~~~cl\_khr\_icd \\ %% ~~~~~~~~~~~~~~~~~~~~~cl\_khr\_local\_int32\_base\_atomics \\ %% ~~~~~~~~~~~~~~~~~~~~~cl\_khr\_local\_int32\_extended\_atomics \\ %% ~~~~~~~~~~~~~~~~~~~~~cl\_nv\_compiler\_options \\ %% ~~~~~~~~~~~~~~~~~~~~~cl\_nv\_copy\_opts \\ %% ~~~~~~~~~~~~~~~~~~~~~cl\_nv\_device\_attribute\_query \\ %% ~~~~~~~~~~~~~~~~~~~~~cl\_nv\_pragma\_unroll \\ %% ~~Search path (expanding ENBLEND\_OPENCL\_PATH and appending built-in path) \\ %% ~~~~/usr/local/share/enblend/kernels:/usr/share/enblend/kernels \\ %% Currently preferred GPU is device \#1 on platform \#2 (auto-detected). %% \end{terminal} %% \end{maxipage} %% %% \caption[Sample \acronym{OpenCL} configuration.]% %% {\label{ex:opencl-config}% %% A sample \acronym{OpenCL} configuration as detected by \App.} %% \end{exemplar} \label{opt:show-image-formats}% \optidx[\defininglocation]{--show-image-formats}% \genidx{format!image}% \gensee{image formats}{format, image}% \item[--show-image-formats]\itemend Show all recognized image formats, their filename extensions and the supported per-channel depths. Depending on the build-time configuration and the operating system, the binary supports different image formats, typically: \acronym{BMP}, \acronym{EXR}, \acronym{GIF}, \acronym{HDR}, \acronym{JPEG}, \acronym{PNG}, \acronym{PNM}, SUN, \acronym{TIFF}, and~\acronym{VIFF} and recognizes different image-filename extensions, again typically: \filename{bmp}, \filename{exr}, \filename{gif}, \filename{hdr}, \filename{jpeg}, \filename{jpg}, \filename{pbm}, \filename{pgm}, \filename{png}, \filename{pnm}, \filename{ppm}, \filename{ras}, \filename{tif}, \filename{tiff}, and~\filename{xv}. The maximum number of different per-channel depths any \appcmd{} provides is seven: \begin{compactitemize} \item 8~bits unsigned integral, \sample{uint8} \item 16~bits unsigned or signed integral, \sample{uint16} or \sample{int16} \item 32~bits unsigned or signed integral, \sample{uint32} or \sample{int32} \item 32~bits floating-point, \sample{float} \item 64~bits floating-point, \sample{double} \end{compactitemize} \label{opt:show-signature}% \optidx[\defininglocation]{--show-signature}% \genidx{signature}% \item[--show-signature]\itemend Show the user name of the person who compiled the binary, when the binary was compiled, and on which machine this was done. This information can be helpful to ensure the binary was created by a trustworthy builder. \label{opt:show-software-components}% \optidx[\defininglocation]{--show-software-components}% \genidx{information!on software components}% \gensee{software!components}{information, on software components}% \genidx{dynamic-library environment}% \genidx{header files}% \item[--show-software-components]\itemend Show the name and version of the compiler that built \App{} followed by the versions of all important libraries against which \App{} was compiled and linked. Technically, the version information is taken from header files, thus it is independent of the dynamic-library environment the binary runs within. The library versions printed here can help to reveal version mismatches with respect to the actual dynamic libraries available to the binary. \label{opt:version}% \optidx[\defininglocation]{--version}% \shoptidx{-V}{--version}% \genidx{software!version}% \gensee{version}{software, version}% \gensee{binary version}{software, version}% \item[\itempar{-V \\ --version}]\itemend Output information on the binary's version. Team this option with \flexipageref{\option{--verbose}}{opt:verbose} to show configuration details, like the extra features that may have been compiled in. For details consult \sectionName~\fullref{sec:exact-version}. \end{codelist} \genidx[\rangeendlocation]{information options} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/doc/enblend-flow-charts.tex0000644000175000017500000000406312672526522016333 00000000000000%% This file is part of Enblend. %% Licence details can be found in the file COPYING. \subsection[Program Flow Charts]{\label{sec:program-flow-and-option-settings}% \genidx[\rangebeginlocation]{program flow}% \genidx{options!program flow}% \gensee{flow}{program flow}% Program Flow And Option Settings} \genidx{program flow!internal}% \figureName~\ref{fig:internal-enblend-flow} depicts \App's internal work flow and shows what option influences which part. \App{} works incrementally. Thus, no matter whether starting with the first image or the result of blending any previous images, it loads the next image. After blending it the result again is a single image, which serves as base for the next input image, this is the next iteration. \begin{figure} \begin{maxipage} \centering \includeimage{internal-enblend-flow} \caption[Internal work flow]{\label{fig:internal-enblend-flow}\App's internal work flow for the ``next'' image. The defaults are indicated like \sample{[default]}. The Optimizer Chain is complicated enough to warrant its own chart in \figureName~\ref{fig:internal-optimizer-chain}.} \end{maxipage} \end{figure} \begin{geeknote} \figureName~\ref{fig:internal-enblend-flow} somewhat simplifies the program flow. \begin{itemize} \item The Graph Cut algorithm needs an initial ``guess'' of the seam line. It gets it by running a Nearest-Feature Transform. \item If the overlap between the previous image and the next image is too small, the ``Scale down mask'' step is skipped and \App{} works with the mask in its original size (``fine mask'') no matter what the command-line options specify. \end{itemize} \end{geeknote} \begin{figure} \begin{maxipage} \centering \includeimage{internal-optimizer-chain} \caption[Optimizer chain]{\label{fig:internal-optimizer-chain}A closer look the Optimizer Chain of \figureName~\ref{fig:internal-enblend-flow}.} \end{maxipage} \end{figure} \genidx[\rangeendlocation]{program flow} %%% Local Variables: %%% fill-column: 96 %%% End: enblend-enfuse-4.2/src/0000755000175000017500000000000012676432767012065 500000000000000enblend-enfuse-4.2/src/enblend.cc0000644000175000017500000031553612676175540013731 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H #include #endif #ifndef ENBLEND_SOURCE #error trying to compile enblend.cc without having defined ENBLEND_SOURCE #endif #ifdef ENFUSE_SOURCE #error must not define ENFUSE_SOURCE when compiling enblend.cc #endif #ifdef _WIN32 // Make sure we bring in windows.h the right way #define _STLP_VERBOSE_AUTO_LINK #define _USE_MATH_DEFINES #define NOMINMAX #define VC_EXTRALEAN #include #undef DIFFERENCE #endif // _WIN32 #ifdef __GW32C__ #undef malloc #define BOOST_NO_STDC_NAMESPACE 1 #endif #include #include #include #include // std::unique_ptr #include #include #include extern "C" char *optarg; extern "C" int optind; #ifndef _MSC_VER #include #endif #include #include #include #include #ifdef _WIN32 #include #endif #include #include #if !defined(LCMS_VERSION) || LCMS_VERSION < 2050 #error "Little CMS version 2.5 or later is required" #endif #include "alternativepercentage.h" #include "global.h" #include "layer_selection.h" #include "parameter.h" #include "selector.h" #include "self_test.h" #include "signature.h" #include "tiff_message.h" #ifdef _MSC_VER #include "win32helpers/delayHelper.h" #endif typedef enum { UnknownDifference, HueLuminanceMaxDifference, // maximum of hue difference and luminance difference DeltaEDifference // L*a*b*-based Delta E } difference_functor_t; typedef struct { unsigned int kmax; // maximum number of moves for a line segment double tau; // temperature reduction factor, "cooling factor"; 0 < tau < 1 double deltaEMax; // maximum cost change possible by any single annealing move double deltaEMin; // minimum cost change possible by any single annealing move } anneal_para_t; // Globals const std::string command("enblend"); const int minimumVectorizeDistance = 4; //< minimum-vectorize-distance 4 const int coarseMaskVectorizeDistance = 4; //< coarse-mask-vectorize-distance 4 const int fineMaskVectorizeDistance = 20; //< fine-mask-vectorize-distance 20 // Global values from command line parameters. std::string OutputFileName(DEFAULT_OUTPUT_FILENAME); int Verbose = 1; //< default-verbosity-level 1 int ExactLevels = 0; // 0 means: automatically calculate maximum bool OneAtATime = true; boundary_t WrapAround = OpenBoundaries; bool GimpAssociatedAlphaHack = false; blend_colorspace_t BlendColorspace = UndeterminedColorspace; bool OutputSizeGiven = false; int OutputWidthCmdLine = 0; int OutputHeightCmdLine = 0; int OutputOffsetXCmdLine = 0; int OutputOffsetYCmdLine = 0; MainAlgo MainAlgorithm = GraphCut; bool Checkpoint = false; bool OptimizeMask = true; bool CoarseMask = true; unsigned CoarsenessFactor = 8U; //< default-coarseness-factor 8 difference_functor_t PixelDifferenceFunctor = DeltaEDifference; //< default-difference-functor Delta-E double LuminanceDifferenceWeight = 1.0; //< default-luminance-difference-weight 1.0 double ChrominanceDifferenceWeight = 1.0; //< default-chrominance-difference-weight 1.0 bool SaveMasks = false; bool StopAfterMaskGeneration = false; std::string SaveMaskTemplate("mask-%n.tif"); //< default-mask-template mask-%n.tif bool LoadMasks = false; std::string LoadMaskTemplate(SaveMaskTemplate); std::string VisualizeTemplate("vis-%n.tif"); //< default-visualize-template vis-%n.tif bool VisualizeSeam = false; std::pair OptimizerWeights = std::make_pair(8.0, //< default-optimizer-weight-distance 8.0 1.0); //< default-optimizer-weight-mismatch 1.0 anneal_para_t AnnealPara = { 32, //< default-anneal-kmax 32 0.75, //< default-anneal-tau 0.75 7000.0, //< default-anneal-deltae-max 7000.0 5.0 //< default-anneal-deltae-min 5.0 }; unsigned int DijkstraRadius = 25U; //< default-dijkstra-radius 25 AlternativePercentage MaskVectorizeDistance(0.0, false); std::string OutputCompression; std::string OutputPixelType; TiffResolution ImageResolution; bool OutputIsValid = true; bool UseGPU = false; namespace cl {class Context;} cl::Context* GPUContext = nullptr; namespace ocl {class BatchBuilder;} ocl::BatchBuilder* BatchCompiler = nullptr; // Globals related to catching SIGINT #ifndef _WIN32 sigset_t SigintMask; #endif // Objects for ICC profiles cmsHPROFILE InputProfile = nullptr; cmsHPROFILE XYZProfile = nullptr; cmsHPROFILE LabProfile = nullptr; cmsHTRANSFORM InputToXYZTransform = nullptr; cmsHTRANSFORM XYZToInputTransform = nullptr; cmsHTRANSFORM InputToLabTransform = nullptr; cmsHTRANSFORM LabToInputTransform = nullptr; cmsViewingConditions ViewingConditions; cmsHANDLE CIECAMTransform = nullptr; cmsHPROFILE FallbackProfile = nullptr; Signature sig; LayerSelectionHost LayerSelection; #include #include #include #include #include "common.h" #include "filespec.h" #include "introspection.h" #include "enblend.h" #ifdef DMALLOC #include "dmalloc.h" // must be last #include #endif #ifdef _WIN32 #define strdup _strdup #endif #ifdef OPENCL namespace GPU { std::unique_ptr StateProbabilities = nullptr; std::unique_ptr DistanceTransform = nullptr; } #endif difference_functor_t differenceFunctorOfString(const char* aDifferenceFunctorName) { std::string name(aDifferenceFunctorName); name.erase(std::remove_if(name.begin(), name.end(), [](char c) {return c == '-';}), name.end()); enblend::to_lower(name); if (name == "maximumhueluminance" || name == "maximumhuelum" || name == "maxhueluminance" || name == "maxhuelum" || name == "max") { return HueLuminanceMaxDifference; } else if (name == "deltae" || name == "de") { return DeltaEDifference; } else { return UnknownDifference; } } #define DUMP_GLOBAL_VARIABLES(...) dump_global_variables(__FILE__, __LINE__, ##__VA_ARGS__) void dump_global_variables(const char* file, unsigned line, std::ostream& out = std::cout) { out << "+ " << file << ":" << line << ": state of global variables\n" << "+ Verbose = " << Verbose << ", option \"--verbose\"\n" << "+ OutputFileName = <" << OutputFileName << ">\n" << "+ ExactLevels = " << ExactLevels << "\n" << "+ UseGPU = " << UseGPU << "\n" << "+ OneAtATime = " << enblend::stringOfBool(OneAtATime) << ", option \"-a\"\n" << "+ WrapAround = " << enblend::stringOfWraparound(WrapAround) << ", option \"--wrap\"\n" << "+ GimpAssociatedAlphaHack = " << enblend::stringOfBool(GimpAssociatedAlphaHack) << ", option \"-g\"\n" << "+ BlendColorspace = " << BlendColorspace << ", option \"--blend-colorspace\"\n" << "+ FallbackProfile = " << (FallbackProfile ? enblend::profileDescription(FallbackProfile) : "[none]") << ", option \"--fallback-profile\"\n" << "+ OutputSizeGiven = " << enblend::stringOfBool(OutputSizeGiven) << ", option \"-f\"\n" << "+ OutputWidthCmdLine = " << OutputWidthCmdLine << ", argument to option \"-f\"\n" << "+ OutputHeightCmdLine = " << OutputHeightCmdLine << ", argument to option \"-f\"\n" << "+ OutputOffsetXCmdLine = " << OutputOffsetXCmdLine << ", argument to option \"-f\"\n" << "+ OutputOffsetYCmdLine = " << OutputOffsetYCmdLine << ", argument to option \"-f\"\n" << "+ Checkpoint = " << enblend::stringOfBool(Checkpoint) << ", option \"-x\"\n" << "+ OptimizeMask = " << enblend::stringOfBool(OptimizeMask) << ", options \"--optimize\" and \"--no-optimize\"\n" << "+ CoarseMask = " << enblend::stringOfBool(CoarseMask) << ", options \"--coarse-mask\" and \"--fine-mask\"\n" << "+ CoarsenessFactor = " << CoarsenessFactor << ", argument to option \"--coarse-mask\"\n" << "+ PixelDifferenceFunctor = " << stringOfPixelDifferenceFunctor(PixelDifferenceFunctor) << "+ LuminanceDifferenceWeight = " << LuminanceDifferenceWeight << "\n" << "+ ChrominanceDifferenceWeight = " << ChrominanceDifferenceWeight << ", option \"--image-difference\"\n" << "+ SaveMasks = " << enblend::stringOfBool(SaveMasks) << ", option \"--save-masks\"\n" << "+ SaveMaskTemplate = <" << SaveMaskTemplate << ">, argument to option \"--save-masks\"\n" << "+ LoadMasks = " << enblend::stringOfBool(LoadMasks) << ", option \"--load-masks\"\n" << "+ LoadMaskTemplate = <" << LoadMaskTemplate << ">, argument to option \"--load-masks\"\n" << "+ VisualizeSeam = " << enblend::stringOfBool(VisualizeSeam) << ", option \"--visualize\"\n" << "+ VisualizeTemplate = <" << VisualizeTemplate << ">, argument to option \"--visualize\"\n" << "+ OptimizerWeights = {\n" << "+ distance = " << OptimizerWeights.first << ",\n" << "+ mismatch = " << OptimizerWeights.second << "\n" << "+ }, arguments to option \"--visualize\"\n" "+ AnnealPara = {\n" << "+ kmax = " << AnnealPara.kmax << ",\n" << "+ tau = " << AnnealPara.tau << ",\n" << "+ deltaEMax = " << AnnealPara.deltaEMax << ",\n" << "+ deltaEMin = " << AnnealPara.deltaEMin << "\n" << "+ }, arguments to option \"--anneal\"\n" << "+ DijkstraRadius = " << DijkstraRadius << ", option \"--dijkstra\"\n" << "+ MaskVectorizeDistance = {\n" << "+ value = " << MaskVectorizeDistance.value() << ",\n" << "+ is_percentage = " << enblend::stringOfBool(MaskVectorizeDistance.is_percentage()) << "\n" << "+ }, arguments to option \"--mask-vectorize\"\n" << "+ OutputCompression = <" << OutputCompression << ">, option \"--compression\"\n" << "+ OutputPixelType = <" << OutputPixelType << ">, option \"--depth\"\n" << "+ end of global variable dump\n"; } void printUsage(const bool error = true) { std::cout << "Usage: enblend [options] [--output=IMAGE] INPUT...\n" << "Blend INPUT images into a single IMAGE.\n" << "\n" << "INPUT... are image filenames or response filenames. Response\n" << "filenames start with an \"" << RESPONSE_FILE_PREFIX_CHAR << "\" character.\n" "\n" << "Options:\n" << "Common options:\n" << " -l, --levels=LEVELS limit number of blending LEVELS to use (1 to " << MAX_PYRAMID_LEVELS << ");\n" << " negative number of LEVELS decreases maximum;\n" << " \"auto\" restores the default automatic maximization\n" << " -o, --output=FILE write output to FILE; default: \"" << OutputFileName << "\"\n" << " -v, --verbose[=LEVEL] verbosely report progress; repeat to\n" << " increase verbosity or directly set to LEVEL\n" << " --compression=COMPRESSION\n" << " set compression of output image to COMPRESSION,\n" << " where COMPRESSION is:\n" << " \"deflate\", \"jpeg\", \"lzw\", \"none\", \"packbits\", for TIFF files and\n" << " 0 to 100, or \"jpeg\", \"jpeg-arith\" for JPEG files,\n" << " where \"jpeg\" and \"jpeg-arith\" accept a compression level\n" << #ifdef OPENCL " --gpu employ GPU in addition to CPU for selected computations; negate\n" << " with \"--no-gpu\"\n" << #endif "\n" << "Advanced options:\n" << " --blend-colorspace=COLORSPACE\n" << " force COLORSPACE for blending operations; Enblend uses\n" << " \"CIELUV\" for images with ICC-profile and \"IDENTITY\" for\n" << " those without and also for all floating-point images;\n" << " other available blend color spaces are \"CIELAB\" and\n" << " \"CIECAM\"\n" << " -c, --ciecam use CIECAM02 to blend colors; disable with \"--no-ciecam\";\n" << " note that this option will be withdrawn in favor of\n" << " \"--blend-colorspace\"\n" << " -d, --depth=DEPTH set the number of bits per channel of the output\n" << " image, where DEPTH is \"8\", \"16\", \"32\", \"r32\", or \"r64\"\n" << " -f WIDTHxHEIGHT[+xXOFFSET+yYOFFSET]\n" << " manually set the size and position of the output\n" << " image; useful for cropped and shifted input\n" << " TIFF images, such as those produced by Nona\n" << " -g associated-alpha hack for Gimp (before version 2)\n" << " and Cinepaint\n" << " -w, --wrap[=MODE] wrap around image boundary, where MODE is \"none\",\n" << " \"horizontal\", \"vertical\", or \"both\"; default: " << enblend::stringOfWraparound(WrapAround) << ";\n" << " without argument the option selects horizontal wrapping\n" << "\n" << "Mask generation options:\n" << " --coarse-mask[=FACTOR] shrink overlap regions by FACTOR to speedup mask\n" << " generation; this is the default; if omitted FACTOR\n" << " defaults to " << CoarsenessFactor << "\n" << " --fine-mask generate mask at full image resolution; use e.g.\n" << " if overlap regions are very narrow\n" << " --optimize turn on mask optimization; this is the default;\n" << " disable with \"--no-optimize\"\n" << " --save-masks[=TEMPLATE]\n" << " save generated masks in TEMPLATE; default: \"" << SaveMaskTemplate << "\";\n" << " conversion chars: \"%i\": mask index, \"%n\": mask number,\n" << " \"%p\": full path, \"%d\": dirname, \"%b\": basename,\n" << " \"%f\": filename, \"%e\": extension; lowercase characters\n" << " refer to input images uppercase to the output image\n" << " --load-masks[=TEMPLATE]\n" << " use existing masks in TEMPLATE instead of generating\n" << " them; same template characters as \"--save-masks\";\n" << " default: \"" << LoadMaskTemplate << "\"\n" << " --visualize[=TEMPLATE] save results of optimizer in TEMPLATE; same template\n" << " characters as \"--save-masks\"; default: \"" << VisualizeTemplate << "\"\n" << "\n" << "Expert options:\n" << " -a, --pre-assemble pre-assemble non-overlapping images; negate with \"--no-pre-assemble\"\n" << " -x checkpoint partial results\n" << " --fallback-profile=PROFILE-FILE\n" << " use the ICC profile from PROFILE-FILE instead of sRGB\n" << " --layer-selector=ALGORITHM\n" << " set the layer selector ALGORITHM;\n" << " default: \"" << LayerSelection.name() << "\"; available algorithms are:\n"; for (selector::algorithm_list::const_iterator i = selector::algorithms.begin(); i != selector::algorithms.end(); ++i) { std::cout << " \"" << (*i)->name() << "\": " << (*i)->description() << "\n"; } std::cout << #ifdef OPENCL " --prefer-gpu=DEVICE select DEVICE on auto-detected platform as GPU\n" << " --prefer-gpu=PLATFORM:DEVICE\n" << " select DEVICE on PLATFORM as GPU\n" << #endif " --parameter=KEY1[=VALUE1][:KEY2[=VALUE2][:...]]\n" << " set one or more KEY-VALUE pairs\n" << "\n" << "Expert mask generation options:\n" << " --primary-seam-generator=ALGORITHM\n" << " use main seam finder ALGORITHM, where ALGORITHM is\n"<< " \"nearest-feature-transform\" or \"graph-cut\";\n" << " default: \"graph-cut\"\n" << " --image-difference=ALGORITHM[:LUMINANCE-WEIGHT[:CHROMINANCE-WEIGHT]]\n" << " use ALGORITHM for calculation of the difference image,\n" << " where ALGORITHM is \"max-hue-luminance\" or \"delta-e\";\n" << " LUMINANCE-WEIGHT and CHROMINANCE-WEIGHT define the\n" << " weights of lightness and color; default: " << stringOfPixelDifferenceFunctor(PixelDifferenceFunctor) << ":" << LuminanceDifferenceWeight << ":" << ChrominanceDifferenceWeight << "\n" << " --optimizer-weights=DISTANCE-WEIGHT[:MISMATCH-WEIGHT]\n" << " set the optimizer's weigths for distance and mismatch;\n" << " default: " << OptimizerWeights.first << ':' << OptimizerWeights.second << "\n" << " --mask-vectorize=LENGTH\n" << " set LENGTH of single seam segment; append \"%\" for\n" << " relative value; defaults: " << coarseMaskVectorizeDistance << " for coarse masks and\n" << " " << fineMaskVectorizeDistance << " for fine masks\n" << " --anneal=TAU[:DELTAE-MAX[:DELTAE-MIN[:K-MAX]]]\n" << " set annealing parameters of optimizer strategy 1;\n" << " defaults: " << AnnealPara.tau << ':' << AnnealPara.deltaEMax << ':' << AnnealPara.deltaEMin << ':' << AnnealPara.kmax << "\n" << " --dijkstra=RADIUS set search RADIUS of optimizer strategy 2; default:\n" << " " << DijkstraRadius << " pixels\n" << "\n" << "Information options:\n" << " -h, --help print this help message and exit\n" << " -V, --version output version information and exit\n" << " --show-globbing-algorithms\n" << " show all globbing algorithms\n" << #ifdef OPENCL " --show-gpu-info list all available GPUs according to their platform and device;\n" << " inform on current preferences\n" << #endif " --show-image-formats show all recognized image formats and their filename\n" << " extensions\n" << " --show-signature show who compiled the binary when and on which machine\n" << " --show-software-components\n" << " show the software components with which Enblend was compiled\n" << "\n" << "Enblend accepts arguments to any option in uppercase as\n" << "well as in lowercase letters.\n" << #if defined(CACHE_IMAGES) || \ defined(OPENMP) || \ (defined(OPENCL) && defined(PREFER_SEPARATE_OPENCL_SOURCE)) "\n" << "Environment:\n" << #endif #ifdef CACHE_IMAGES " TMPDIR The TMPDIR environment variable points to the directory,\n" << " where to store ImageCache files. If unset Enblend uses \"/tmp\".\n" << #endif #ifdef OPENMP " OMP_NUM_THREADS The OMP_NUM_THREADS environment variable sets the number\n" << " of threads to use in OpenMP parallel regions. If unset\n" << " Enblend uses as many threads as there are CPUs.\n" << " OMP_DYNAMIC The OMP_DYNAMIC environment variable controls dynamic\n" << " adjustment of the number of threads to use in executing\n" << " OpenMP parallel regions.\n" << #endif #if defined(OPENCL) && defined(PREFER_SEPARATE_OPENCL_SOURCE) " ENBLEND_OPENCL_PATH The ENBLEND_OPENCL_PATH environment variable sets the search\n" << " path for OpenCL source files.\n" << #endif "\n" << "Report bugs at <" PACKAGE_BUGREPORT ">." << std::endl; exit(error ? 1 : 0); } void cleanup_output(void) { if (!OutputIsValid) { std::cerr << command << ": info: remove invalid output image \"" << OutputFileName << "\"\n"; errno = 0; if (unlink(OutputFileName.c_str()) != 0) { std::cerr << command << ": warning: could not remove invalid output image \"" << OutputFileName << "\": " << enblend::errorMessage(errno) << "\n"; } } } /** Make sure all cached file images get destroyed, and hence the * temporary files deleted, if we are killed. */ void sigint_handler(int sig) { std::cerr << std::endl << command << ": interrupted" << std::endl; cleanup_output(); #if !defined(__GW32C__) && !defined(_WIN32) struct sigaction action; action.sa_handler = SIG_DFL; action.sa_flags = 0; sigemptyset(&(action.sa_mask)); sigaction(sig, &action, nullptr); #else signal(sig, SIG_DFL); #endif raise(sig); } enum AllPossibleOptions { VersionOption, PreAssembleOption /* -a */, NoPreAssembleOption, HelpOption, LevelsOption, OutputOption, VerboseOption, WrapAroundOption /* -w */, CheckpointOption /* -x */, CompressionOption, LZWCompressionOption, BlendColorspaceOption, CIECAM02Option, NoCIECAM02Option, FallbackProfileOption, DepthOption, AssociatedAlphaOption /* -g */, GPUOption, NoGPUOption, PreferredGPUOption, SizeAndPositionOption /* -f */, VisualizeOption, CoarseMaskOption, FineMaskOption, OptimizeOption, NoOptimizeOption, SaveMasksOption, LoadMasksOption, ImageDifferenceOption, AnnealOption, DijkstraRadiusOption, MaskVectorizeDistanceOption, OptimizerWeightsOption, LayerSelectorOption, NearestFeatureTransformOption, GraphCutOption, ShowImageFormatsOption, ShowSignatureOption, ShowGlobbingAlgoInfoOption, ShowSoftwareComponentsInfoOption, ShowGPUInfoOption, // currently below the radar... SequentialBlendingOption }; typedef std::set OptionSetType; bool contains(const OptionSetType& optionSet, enum AllPossibleOptions anOption) { return optionSet.count(anOption) != 0; } /** Warn if options given at the command line have no effect. */ void warn_of_ineffective_options(const OptionSetType& optionSet) { if (contains(optionSet, LoadMasksOption)) { if (contains(optionSet, VisualizeOption)) { std::cerr << command << ": warning: option \"--visualize\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, CoarseMaskOption)) { std::cerr << command << ": warning: option \"--coarse-mask\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, FineMaskOption)) { std::cerr << command << ": warning: option \"--fine-mask\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, OptimizeOption)) { std::cerr << command << ": warning: option \"--optimize\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, NoOptimizeOption)) { std::cerr << command << ": warning: option \"--no-optimize\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, AnnealOption)) { std::cerr << command << ": warning: option \"--anneal\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, DijkstraRadiusOption)) { std::cerr << command << ": warning: option \"--dijkstra\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, MaskVectorizeDistanceOption)) { std::cerr << command << ": warning: option \"--mask-vectorize\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, OptimizerWeightsOption)) { std::cerr << command << ": warning: option \"--optimizer-weights\" has no effect with \"--load-masks\"" << std::endl; } } if (contains(optionSet, SaveMasksOption) && !contains(optionSet, OutputOption)) { if (contains(optionSet, LevelsOption)) { std::cerr << command << ": warning: option \"--levels\" has no effect with \"--save-masks\" and no \"--output\"" << std::endl; } if (contains(optionSet, WrapAroundOption)) { std::cerr << command << ": warning: option \"--wrap\" has no effect with \"--save-masks\" and no \"--output\"" << std::endl; } if (contains(optionSet, CompressionOption)) { std::cerr << command << ": warning: option \"--compression\" has no effect with \"--save-masks\" and no \"--output\"" << std::endl; } if (contains(optionSet, DepthOption)) { std::cerr << command << ": warning: option \"--depth\" has no effect with \"--save-masks\" and no \"--output\"" << std::endl; } if (contains(optionSet, SizeAndPositionOption)) { std::cerr << command << ": warning: option \"-f\" has no effect with \"--save-masks\" and no \"--output\"" << std::endl; } } if (contains(optionSet, CompressionOption) && !(enblend::getFileType(OutputFileName) == "TIFF" || enblend::getFileType(OutputFileName) == "JPEG")) { std::cerr << command << ": warning: compression is not supported with output\n" << command << ": warning: file type \"" << enblend::getFileType(OutputFileName) << "\"" << std::endl; } if (contains(optionSet, AssociatedAlphaOption) && enblend::getFileType(OutputFileName) != "TIFF") { std::cerr << command << ": warning: option \"-g\" has no effect with output\n" << command << ": warning: file type \"" << enblend::getFileType(OutputFileName) << "\"" << std::endl; } if (!OptimizeMask) { if (contains(optionSet, AnnealOption)) { std::cerr << command << ": warning: option \"--anneal\" without mask optimization has\n" << command << ": warning: no effect" << std::endl; } if (contains(optionSet, DijkstraRadiusOption)) { std::cerr << command << ": warning: option \"--dijkstra\" without mask optimization\n" << command << ": warning: has no effect" << std::endl; } if (contains(optionSet, OptimizerWeightsOption)) { std::cerr << command << ": warning: option \"--optimizer-weights\" without mask optimization\n" << command << ": warning: has no effect" << std::endl; } } if (!(OptimizeMask || CoarseMask) && contains(optionSet, MaskVectorizeDistanceOption)) { std::cerr << command << ": warning: option \"--mask-vectorize\" without mask optimization\n" << command << ": warning: or coarse mask has no effect" << std::endl; } if (!CoarseMask && MainAlgorithm == GraphCut && contains(optionSet, FineMaskOption)) { std::cerr << command << ": warning: option \"--fine-mask\" combined with option \"--primary-seam-generator=graphcut\"\n" << command << ": warning: incompatible with mask optimization,\n" << command << ": note: defaulting to no optimization" << std::endl; OptimizeMask = false; } #ifdef OPENCL if (!UseGPU && contains(optionSet, PreferredGPUOption)) { std::cerr << command << ": warning: option \"--preferred-gpu\" has no effect without enabled GPU" << std::endl; } #else if (contains(optionSet, GPUOption)) { std::cerr << command << ": warning: option \"--gpu\" has no effect in this " << command << " binary,\n" << command << ": warning: because " << command << " was compiled without support for OpenCL" << std::endl; } if (contains(optionSet, NoGPUOption)) { std::cerr << command << ": warning: option \"--no-gpu\" has no effect in this " << command << " binary,\n" << command << ": warning: because " << command << " was compiled without support for OpenCL" << std::endl; } if (contains(optionSet, PreferredGPUOption)) { std::cerr << command << ": warning: option \"--prefer-gpu\" has no effect in this " << command << " binary,\n" << command << ": warning: because " << command << " was compiled without support for OpenCL" << std::endl; } #endif // OPENCL } const struct option* lookup_long_option_by_id(struct option* an_option_array, int a_long_option_id) { assert(an_option_array != nullptr); struct option* opt = an_option_array; while (opt->name != 0) { if (opt->val == a_long_option_id) { return opt; } ++opt; } return nullptr; } bool short_option_requires_argument(const char* a_short_option_spec, char a_short_option) { if (a_short_option != 0) { const char* c = strchr(a_short_option_spec, a_short_option); if (c != nullptr) { if (*(c + 1) == ':' && *(c + 2) != ':') { return true; } } } return false; } #ifdef OPENCL void initialize_gpu_subsystem(size_t a_preferred_gpu_platform, size_t a_preferred_gpu_device) { try { cl::Platform platform = ocl::find_platform(a_preferred_gpu_platform); ocl::device_list_t devices; ocl::prefer_device(platform, a_preferred_gpu_platform, a_preferred_gpu_device, devices); GPUContext = ocl::create_context(platform, devices); if (Verbose >= VERBOSE_OPENCL_MESSAGES) { std::cerr << command << ": info: chose OpenCL platform #" << a_preferred_gpu_platform << ", "; std::string info; platform.getInfo(CL_PLATFORM_VENDOR, &info); std::cerr << info << ", "; platform.getInfo(CL_PLATFORM_NAME, &info); std::cerr << info << ", device #" << a_preferred_gpu_device << std::endl; } #ifdef OPENMP BatchCompiler = new ocl::ThreadedBatchBuilder; #else BatchCompiler = new ocl::SerialBatchBuilder; #endif } catch (ocl::runtime_error& an_exception) { std::cerr << command << ": warning: " << an_exception.what() << ";\n" << command << ": warning: " << " cannot enable GPU" << std::endl; } if (!gpu_is_ok(GPUContext)) { std::cerr << command << ": warning: at least one of Enfuse's GPU tests has failed\n" << command << ": note: refusing to activate GPU support" << std::endl; delete GPUContext; delete BatchCompiler; GPUContext = nullptr; BatchCompiler = nullptr; } } #endif // OPENCL int process_options(int argc, char** argv) { enum OptionId { OPTION_ID_OFFSET = 1023, // Ids start at 1024 UseGpuId, NoUseGpuId, PreferGpuId, PreAssembleId, NoPreAssembleId, CoarseMaskId, FineMaskId, OptimizeMaskId, NoOptimizeMaskId, SaveMaskId, LoadMaskId, VisualizeId, AnnealId, DijkstraRadiusId, MaskVectorizeDistanceId, CompressionId, VerboseId, HelpId, VersionId, DepthId, OutputId, WrapAroundId, OptimizerWeightsId, LevelsId, BlendColorspaceId, CiecamId, NoCiecamId, FallbackProfileId, LayerSelectorId, MainAlgoId, ImageDifferenceId, ParameterId, NoParameterId, ImageFormatsInfoId, SignatureInfoId, GlobbingAlgoInfoId, SoftwareComponentsInfoId, GPUInfoId }; static struct option long_options[] = { {"gpu", no_argument, 0, UseGpuId}, {"no-gpu", no_argument, 0, NoUseGpuId}, {"prefer-gpu", required_argument, 0, PreferGpuId}, {"preferred-gpu", required_argument, 0, PreferGpuId}, // gramatically close alternative form {"pre-assemble", no_argument, 0, PreAssembleId}, {"preassemble", no_argument, 0, PreAssembleId}, // dash-less form: not documented, not deprecated {"no-pre-assemble", no_argument, 0, NoPreAssembleId}, {"no-preassemble", no_argument, 0, NoPreAssembleId}, // dash-less form: not documented, not deprecated {"coarse-mask", optional_argument, 0, CoarseMaskId}, {"fine-mask", no_argument, 0, FineMaskId}, {"optimize", no_argument, 0, OptimizeMaskId}, {"no-optimize", no_argument, 0, NoOptimizeMaskId}, {"save-mask", optional_argument, 0, SaveMaskId}, // singular form: not documented, not deprecated {"save-masks", optional_argument, 0, SaveMaskId}, {"load-mask", optional_argument, 0, LoadMaskId}, // singular form: not documented, not deprecated {"load-masks", optional_argument, 0, LoadMaskId}, {"visualize", optional_argument, 0, VisualizeId}, {"anneal", required_argument, 0, AnnealId}, {"dijkstra", required_argument, 0, DijkstraRadiusId}, {"mask-vectorize", required_argument, 0, MaskVectorizeDistanceId}, {"compression", required_argument, 0, CompressionId}, {"verbose", optional_argument, 0, VerboseId}, {"help", no_argument, 0, HelpId}, {"version", no_argument, 0, VersionId}, {"depth", required_argument, 0, DepthId}, {"output", required_argument, 0, OutputId}, {"wrap", optional_argument, 0, WrapAroundId}, {"optimizer-weights", required_argument, 0, OptimizerWeightsId}, {"levels", required_argument, 0, LevelsId}, {"blend-colorspace", required_argument, 0, BlendColorspaceId}, {"blend-color-space", required_argument, 0, BlendColorspaceId}, // dash form: not documented, not deprecated {"ciecam", no_argument, 0, CiecamId}, {"no-ciecam", no_argument, 0, NoCiecamId}, {"fallback-profile", required_argument, 0, FallbackProfileId}, {"layer-selector", required_argument, 0, LayerSelectorId}, {"primary-seam-generator", required_argument, 0, MainAlgoId}, {"image-difference", required_argument, 0, ImageDifferenceId}, {"parameter", required_argument, 0, ParameterId}, {"no-parameter", required_argument, 0, NoParameterId}, {"show-image-formats", no_argument, 0, ImageFormatsInfoId}, {"show-signature", no_argument, 0, SignatureInfoId}, {"show-globbing-algorithms", no_argument, 0, GlobbingAlgoInfoId}, {"show-software-components", no_argument, 0, SoftwareComponentsInfoId}, {"show-gpu-info", no_argument, 0, GPUInfoId}, {0, 0, 0, 0} }; bool failed = false; typedef enum { PROCESS_COMPLETELY, VERSION_ONLY, USAGE_ONLY, IMAGE_FORMATS_ONLY, SIGNATURE_ONLY, GLOBBING_ALGOS_ONLY, SOFTWARE_COMPONENTS_ONLY, GPU_INFO_COMPONENTS_ONLY } print_only_task_id_t; print_only_task_id_t print_only_task = PROCESS_COMPLETELY; OptionSetType optionSet; #ifdef OPENCL size_t preferredGPUPlatform = 0U; // We start enumerating platforms at 1 for user convenience. // Zero means we choose the first platform found, i.e. auto-detect. size_t preferredGPUDevice = 1U; // We start enumerating platforms at 1 for user convenience. #endif static const char short_options[] = "Vab:cd:f:ghl:m:o:sv::w::x"; opterr = 0; // we have our own "unrecognized option" message while (true) { int option_index = -1; const int code = getopt_long(argc, argv, short_options, long_options, &option_index); if (code == -1) { break; } switch (code) { case UseGpuId: UseGPU = true; optionSet.insert(GPUOption); break; case NoUseGpuId: UseGPU = false; optionSet.insert(NoGPUOption); break; case PreferGpuId: #ifdef OPENCL { char* delimiter = strpbrk(optarg, NUMERIC_OPTION_DELIMITERS); if (delimiter == nullptr) { preferredGPUDevice = enblend::numberOfString(optarg, [](unsigned x) {return x >= 1U;}, "preferred GPU device out of range", 1U); } else { *delimiter = 0; ++delimiter; preferredGPUPlatform = enblend::numberOfString(optarg, [](unsigned x) {return x >= 1U;}, "preferred GPU platform out of range", 1U); preferredGPUDevice = enblend::numberOfString(delimiter, [](unsigned x) {return x >= 1U;}, "preferred GPU device out of range", 1U); } } #endif optionSet.insert(PreferredGPUOption); break; case FineMaskId: CoarseMask = false; optionSet.insert(FineMaskOption); break; case OptimizeMaskId: OptimizeMask = true; optionSet.insert(OptimizeOption); break; case NoOptimizeMaskId: OptimizeMask = false; optionSet.insert(NoOptimizeOption); break; case 'h': BOOST_FALLTHROUGH; case HelpId: print_only_task = USAGE_ONLY; optionSet.insert(HelpOption); break; case 'V': BOOST_FALLTHROUGH; case VersionId: print_only_task = VERSION_ONLY; optionSet.insert(VersionOption); break; case ImageFormatsInfoId: print_only_task = IMAGE_FORMATS_ONLY; optionSet.insert(ShowImageFormatsOption); break; case SignatureInfoId: print_only_task = SIGNATURE_ONLY; optionSet.insert(ShowSignatureOption); break; case GlobbingAlgoInfoId: print_only_task = GLOBBING_ALGOS_ONLY; optionSet.insert(ShowGlobbingAlgoInfoOption); break; case SoftwareComponentsInfoId: print_only_task = SOFTWARE_COMPONENTS_ONLY; optionSet.insert(ShowSoftwareComponentsInfoOption); break; case GPUInfoId: print_only_task = GPU_INFO_COMPONENTS_ONLY; optionSet.insert(ShowGPUInfoOption); break; case 'w': BOOST_FALLTHROUGH; case WrapAroundId: if (optarg != nullptr && *optarg != 0) { WrapAround = enblend::wraparoundOfString(optarg); if (WrapAround == UnknownWrapAround) { std::cerr << command << ": unrecognized wrap-around mode \"" << optarg << "\"\n" << std::endl; failed = true; } } else { WrapAround = HorizontalStrip; } optionSet.insert(WrapAroundOption); break; case SaveMaskId: if (optarg != nullptr && *optarg != 0) { SaveMaskTemplate = optarg; } SaveMasks = true; optionSet.insert(SaveMasksOption); break; case LoadMaskId: if (optarg != nullptr && *optarg != 0) { LoadMaskTemplate = optarg; } LoadMasks = true; optionSet.insert(LoadMasksOption); break; case VisualizeId: if (optarg != nullptr && *optarg != 0) { VisualizeTemplate = optarg; } VisualizeSeam = true; optionSet.insert(VisualizeOption); break; case CompressionId: if (optarg != nullptr && *optarg != 0) { std::string upper_opt(optarg); enblend::to_upper(upper_opt); if (upper_opt == "NONE") { ; // stick with default } else if (upper_opt == "DEFLATE" || upper_opt == "LZW" || upper_opt == "PACKBITS") { OutputCompression = upper_opt; } else if (upper_opt.find_first_not_of("0123456789") == std::string::npos) { OutputCompression = "JPEG QUALITY=" + upper_opt; } else if (enblend::starts_with(upper_opt, "JPEG") || enblend::starts_with(upper_opt, "JPEG-ARITH")) { const std::string::size_type delimiter_position = upper_opt.find_first_of(NUMERIC_OPTION_DELIMITERS); if (delimiter_position == std::string::npos) { if (upper_opt == "JPEG" || upper_opt == "JPEG-ARITH") { OutputCompression = upper_opt; } else { std::cerr << command << ": trailing garbage in JPEG compression \"" << optarg << "\"" << std::endl; failed = true; } } else { const std::string algorithm(upper_opt.substr(0, delimiter_position)); if (algorithm == "JPEG" || algorithm == "JPEG-ARITH") { const std::string level(upper_opt.substr(delimiter_position + 1U)); if (level.length() >= 1U && level.find_first_not_of("0123456789") == std::string::npos) { upper_opt.replace(delimiter_position, 1U, " QUALITY="); OutputCompression = upper_opt; } else { std::cerr << command << ": invalid JPEG compression level \"" << level << "\"" << std::endl; failed = true; } } else { std::cerr << command << ": unrecognized JPEG compression \"" << optarg << "\"" << std::endl; failed = true; } } } else { std::cerr << command << ": unrecognized compression \"" << optarg << "\"" << std::endl; failed = true; } } else { std::cerr << command << ": option \"--compression\" requires an argument" << std::endl; failed = true; } optionSet.insert(CompressionOption); break; case 'd': BOOST_FALLTHROUGH; case DepthId: if (optarg != nullptr && *optarg != 0) { OutputPixelType = enblend::outputPixelTypeOfString(optarg); } else { std::cerr << command << ": options \"-d\" or \"--depth\" require arguments" << std::endl; failed = true; } optionSet.insert(DepthOption); break; case 'o': BOOST_FALLTHROUGH; case OutputId: if (contains(optionSet, OutputOption)) { std::cerr << command << ": warning: more than one output file specified" << std::endl; } if (optarg != nullptr && *optarg != 0) { OutputFileName = optarg; } else { std::cerr << command << ": options \"-o\" or \"--output\" require arguments" << std::endl; failed = true; } optionSet.insert(OutputOption); break; case ImageDifferenceId: { char* tail; boost::char_separator separator(NUMERIC_OPTION_DELIMITERS, "", boost::keep_empty_tokens); const std::string arg(optarg); boost::tokenizer > tokenizer(arg, separator); boost::tokenizer >::iterator token = tokenizer.begin(); if (token == tokenizer.end()) { std::cerr << command << ": option \"--image-difference\" requires an argument" << std::endl; failed = true; } else { PixelDifferenceFunctor = differenceFunctorOfString(token->c_str()); if (PixelDifferenceFunctor == UnknownDifference) { std::cerr << command << ": unknown image difference algorithm \"" << *token << "\"" << std::endl; failed = true; } ++token; } if (token != tokenizer.end()) { errno = 0; LuminanceDifferenceWeight = strtod(token->c_str(), &tail); if (errno == 0) { if (*tail != 0) { std::cerr << command << ": unrecognized luminance weight \"" << tail << "\" in \"" << *token << "\"" << std::endl; failed = true; } if (LuminanceDifferenceWeight < 0.0) { std::cerr << command << ": luminance weight must be non-negative" << std::endl; failed = true; } } else { std::cerr << command << ": illegal numeric format \"" << *token << "\" of luminance weight: " << enblend::errorMessage(errno) << std::endl; failed = true; } ++token; } if (token != tokenizer.end()) { errno = 0; ChrominanceDifferenceWeight = strtod(token->c_str(), &tail); if (errno == 0) { if (*tail != 0) { std::cerr << command << ": unrecognized chrominance weight \"" << tail << "\" in \"" << *token << "\"" << std::endl; failed = true; } if (ChrominanceDifferenceWeight < 0.0) { std::cerr << command << ": chrominance weight must be non-negative" << std::endl; failed = true; } } else { std::cerr << command << ": illegal numeric format \"" << *token << "\" of chrominance weight: " << enblend::errorMessage(errno) << std::endl; failed = true; } ++token; } if (token != tokenizer.end()) { std::cerr << command << ": warning: ignoring trailing garbage \"" << *token << "\" in argument to \"--image-difference\"" << std::endl; } if (LuminanceDifferenceWeight + ChrominanceDifferenceWeight == 0.0) { std::cerr << command << ": luminance weight and chrominance weight cannot both be zero" << std::endl; failed = true; } optionSet.insert(ImageDifferenceOption); break; } case AnnealId: { char* tail; boost::char_separator separator(NUMERIC_OPTION_DELIMITERS, "", boost::keep_empty_tokens); const std::string arg(optarg); boost::tokenizer > tokenizer(arg, separator); boost::tokenizer >::iterator token = tokenizer.begin(); if (token != tokenizer.end()) { errno = 0; double tau = strtod(token->c_str(), &tail); if (errno != 0) { std::cerr << command << ": option \"--anneal\": illegal numeric format \"" << *token << "\" of tau: " << enblend::errorMessage(errno) << std::endl; failed = true; } if (*tail != 0) { if (*tail == '%') { tau /= 100.0; } else { std::cerr << command << ": --anneal: trailing garbage \"" << tail << "\" in tau: \"" << *token << "\"" << std::endl; failed = true; } } //< minimum-anneal-tau 0 if (tau <= 0.0) { std::cerr << command << ": option \"--anneal\": tau must be larger than zero" << std::endl; failed = true; } //< maximum-anneal-tau 1 if (tau >= 1.0) { std::cerr << command << ": option \"--anneal\": tau must be less than one" << std::endl; failed = true; } AnnealPara.tau = tau; ++token; } if (token != tokenizer.end()) { errno = 0; AnnealPara.deltaEMax = strtod(token->c_str(), &tail); if (errno != 0) { std::cerr << command << ": option \"--anneal\": illegal numeric format \"" << *token << "\" of deltaE_max: " << enblend::errorMessage(errno) << std::endl; failed = true; } if (*tail != 0) { std::cerr << command << ": option \"--anneal\": trailing garbage \"" << tail << "\" in deltaE_max: \"" << *token << "\"" << std::endl; failed = true; } //< minimum-anneal-deltae-max 0 if (AnnealPara.deltaEMax <= 0.0) { std::cerr << command << ": option \"--anneal\": deltaE_max must be larger than zero" << std::endl; failed = true; } ++token; } if (token != tokenizer.end()) { errno = 0; AnnealPara.deltaEMin = strtod(token->c_str(), &tail); if (errno != 0) { std::cerr << command << ": option \"--anneal\": illegal numeric format \"" << *token << "\" of deltaE_min: " << enblend::errorMessage(errno) << std::endl; failed = true; } if (*tail != 0) { std::cerr << command << ": option \"--anneal\": trailing garbage \"" << tail << "\" in deltaE_min: \"" << *token << "\"" << std::endl; failed = true; } //< minimum-anneal-deltae-min 0 if (AnnealPara.deltaEMin <= 0.0) { std::cerr << command << ": option \"--anneal\": deltaE_min must be larger than zero" << std::endl; failed = true; } ++token; } if (AnnealPara.deltaEMin >= AnnealPara.deltaEMax) { std::cerr << command << ": option \"--anneal\": deltaE_min must be less than deltaE_max" << std::endl; failed = true; } if (token != tokenizer.end()) { errno = 0; const long int kmax = strtol(token->c_str(), &tail, 10); if (errno != 0) { std::cerr << command << ": option \"--anneal\": illegal numeric format \"" << *token << "\" of k_max: " << enblend::errorMessage(errno) << std::endl; failed = true; } if (*tail != 0) { std::cerr << command << ": option \"--anneal\": trailing garbage \"" << tail << "\" in k_max: \"" << *token << "\"" << std::endl; failed = true; } //< minimum-anneal-kmax 3 if (kmax < 3L) { std::cerr << command << ": option \"--anneal\": k_max must larger or equal to 3" << std::endl; failed = true; } AnnealPara.kmax = static_cast(kmax); } optionSet.insert(AnnealOption); break; } case MaskVectorizeDistanceId: { char* tail; MaskVectorizeDistance.set_percentage(false); errno = 0; MaskVectorizeDistance.set_value(strtod(optarg, &tail)); if (errno != 0) { std::cerr << command << ": option \"--mask-vectorize\": illegal numeric format \"" << optarg << "\": " << enblend::errorMessage(errno) << std::endl; failed = true; } if (*tail != 0) { if (*tail == '%') { MaskVectorizeDistance.set_percentage(true); } else { std::cerr << command << ": option \"--mask-vectorize\": trailing garbage \"" << tail << "\" in \"" << optarg << "\"" << std::endl; failed = true; } } if (MaskVectorizeDistance.value() <= 0.0) { std::cerr << command << ": option \"--mask-vectorize\": distance must be positive" << std::endl; failed = true; } optionSet.insert(MaskVectorizeDistanceOption); break; } case OptimizerWeightsId: { boost::char_separator separator(NUMERIC_OPTION_DELIMITERS, "", boost::keep_empty_tokens); const std::string arg(optarg); boost::tokenizer > tokenizer(arg, separator); boost::tokenizer >::iterator token = tokenizer.begin(); OptimizerWeights.first = enblend::numberOfString(*token, [](double x) {return x >= 0.0;}, "negative optimizer weight; will use 0.0", 0.0); ++token; if (token != tokenizer.end()) { OptimizerWeights.second = enblend::numberOfString(*token, [](double x) {return x >= 0.0;}, "negative optimizer weight; will use 0.0", 0.0); } if (OptimizerWeights.first == 0.0 && OptimizerWeights.second == 0.0) { std::cerr << command << ": optimizer weights cannot be both zero" << std::endl; } optionSet.insert(OptimizerWeightsOption); break; } case 'v': BOOST_FALLTHROUGH; case VerboseId: if (optarg != nullptr && *optarg != 0) { Verbose = enblend::numberOfString(optarg, [](int x) {return x >= 0;}, //< minimum-verbosity-level 0 "verbosity level less than 0; will use 0", 0); } else { Verbose++; } optionSet.insert(VerboseOption); break; case CoarseMaskId: CoarseMask = true; if (optarg != nullptr && *optarg != 0) { CoarsenessFactor = enblend::numberOfString(optarg, [](unsigned x) {return x >= 1U;}, "coarseness factor less or equal to 0; will use 1", 1U); } optionSet.insert(CoarseMaskOption); break; case DijkstraRadiusId: DijkstraRadius = enblend::numberOfString(optarg, [](unsigned x) {return x >= 1U;}, //< minimum-dijkstra-radius 1 "Dijkstra radius is 0; will use 1", 1U); optionSet.insert(DijkstraRadiusOption); break; case 'a': BOOST_FALLTHROUGH; case PreAssembleId: OneAtATime = false; optionSet.insert(PreAssembleOption); break; case NoPreAssembleId: OneAtATime = true; optionSet.insert(NoPreAssembleOption); break; case BlendColorspaceId: if (optarg != nullptr && *optarg != 0) { std::string name(optarg); enblend::to_upper(name); if (name == "IDENTITY" || name == "ID" || name == "UNIT") { BlendColorspace = IdentitySpace; } else if (name == "LAB" || name == "CIELAB" || name == "LSTAR" || name == "L-STAR") { BlendColorspace = CIELAB; } else if (name == "LUV" || name == "CIELUV") { BlendColorspace = CIELUV; } else if (name == "CIECAM" || name == "CIECAM02" || name == "JCH") { BlendColorspace = CIECAM; } else { std::cerr << command << ": unrecognized argument \"" << optarg << "\" of option \"--blend-colorspace\"" << std::endl; failed = true; } } else { std::cerr << command << ": option \"--blend-colorspace\" requires an argument" << std::endl; failed = true; } optionSet.insert(BlendColorspaceOption); break; case 'c': BOOST_FALLTHROUGH; case CiecamId: std::cerr << command << ": info: option \"--ciecam\" will be withdrawn in the next release\n" << command << ": note: prefer option \"--blend-colorspace\" to \"--ciecam\"" << std::endl; BlendColorspace = CIECAM; optionSet.insert(CIECAM02Option); break; case NoCiecamId: std::cerr << command << ": info: option \"--no-ciecam\" will be withdrawn in the next release\n" << command << ": note: prefer option \"--blend-colorspace\" to \"--no-ciecam\"" << std::endl; BlendColorspace = IdentitySpace; optionSet.insert(NoCIECAM02Option); break; case FallbackProfileId: if (enblend::can_open_file(optarg)) { FallbackProfile = cmsOpenProfileFromFile(optarg, "r"); if (FallbackProfile == nullptr) { std::cerr << command << ": failed to open fallback ICC profile file \"" << optarg << "\"\n"; exit(1); } } else { exit(1); } optionSet.insert(FallbackProfileOption); break; case MainAlgoId: if (optarg != nullptr && *optarg != 0) { std::string algo_name(optarg); enblend::to_upper(algo_name); if (algo_name == "GRAPH-CUT" || algo_name == "GRAPHCUT" || algo_name == "GC") { MainAlgorithm = GraphCut; optionSet.insert(GraphCutOption); } else if (algo_name == "NEAREST-FEATURE-TRANSFORM" || algo_name == "NEARESTFEATURETRANSFORM" || algo_name == "NFT") { MainAlgorithm = NFT; optionSet.insert(NearestFeatureTransformOption); } else { std::cerr << command << "unrecognized argument \"" << optarg << "\" of option \"--primary-seam-generator\"" << std::endl; failed = true; } } else { std::cerr << command << ": option \"--primary-seam-generator\" requires an argument" << std::endl; failed = true; } break; case 'f': if (optarg != nullptr && *optarg != 0) { const int n = sscanf(optarg, "%dx%d+%d+%d", &OutputWidthCmdLine, &OutputHeightCmdLine, &OutputOffsetXCmdLine, &OutputOffsetYCmdLine); if (n == 4) { ; // ok: full geometry string } else if (n == 2) { OutputOffsetXCmdLine = 0; OutputOffsetYCmdLine = 0; } else { std::cerr << command << ": option \"-f\" requires 2 or 4 arguments" << std::endl; failed = true; } } else { std::cerr << command << ": option \"-f\" requires 2 or 4 arguments" << std::endl; failed = true; } OutputSizeGiven = true; optionSet.insert(SizeAndPositionOption); break; case 'g': GimpAssociatedAlphaHack = true; optionSet.insert(AssociatedAlphaOption); break; case 'l': BOOST_FALLTHROUGH; case LevelsId: if (optarg != nullptr && *optarg != 0) { std::string levels(optarg); enblend::to_upper(levels); if (levels == "AUTO" || levels == "AUTOMATIC") { ExactLevels = 0; } else if (levels.find_first_not_of("+-0123456789") != std::string::npos) { std::cerr << command << ": options \"-l\" or \"--levels\" require an integer argument or \"auto\"" << std::endl; failed = true; } else { std::ostringstream oss; oss << "cannot use more than " << MAX_PYRAMID_LEVELS << " pyramid levels; will use at most " << MAX_PYRAMID_LEVELS << " levels"; ExactLevels = enblend::numberOfString(optarg, [](int x) {return x != 0;}, "cannot blend with zero levels; will use one level", 1, [](int x) {return x <= MAX_PYRAMID_LEVELS;}, oss.str(), MAX_PYRAMID_LEVELS); } } else { std::cerr << command << ": options \"-l\" or \"--levels\" require an argument" << std::endl; failed = true; } optionSet.insert(LevelsOption); break; case 's': // Deprecated sequential blending flag. OneAtATime = true; std::cerr << command << ": warning: flag \"-s\" is deprecated." << std::endl; optionSet.insert(SequentialBlendingOption); break; case 'x': Checkpoint = true; optionSet.insert(CheckpointOption); break; case LayerSelectorId: { selector::algorithm_list::const_iterator selector = selector::find_by_name(optarg); if (selector != selector::algorithms.end()) { LayerSelection.set_selector(selector->get()); } else { std::cerr << command << ": unknown selector algorithm \"" << optarg << "\""; exit(1); } optionSet.insert(LayerSelectorOption); break; } case ParameterId: { boost::char_separator separator(NUMERIC_OPTION_DELIMITERS, "", boost::keep_empty_tokens); const std::string arg(optarg); boost::tokenizer > tokenizer(arg, separator); boost::tokenizer >::iterator token = tokenizer.begin(); for (auto token = tokenizer.begin(); token != tokenizer.end(); ++token) { std::string key; std::string value; size_t delimiter = token->find_first_of(ASSIGNMENT_CHARACTERS); if (delimiter == std::string::npos) { key = *token; value.assign("1"); } else { key = token->substr(0, delimiter); value = token->substr(delimiter + 1); if (value.empty()) { std::cerr << command << ": parameter key \"" << key << "\" lacks a value;\n" << command << ": note: dangling assignment operator\n"; exit(1); } } enblend::trim(key); enblend::trim(value); if (parameter::is_valid_identifier(key)) { parameter::insert(key, value); } else { std::cerr << command << ": parameter key \"" << key << "\" is not a valid identifier\n"; exit(1); } } break; } case NoParameterId: { boost::char_separator separator(NUMERIC_OPTION_DELIMITERS, "", boost::keep_empty_tokens); const std::string arg(optarg); boost::tokenizer > tokenizer(arg, separator); boost::tokenizer >::iterator token = tokenizer.begin(); for (auto token = tokenizer.begin(); token != tokenizer.end(); ++token) { std::string key(*token); enblend::trim(key); if (key == "*") { parameter::erase_all(); } else if (parameter::is_valid_identifier(key)) { parameter::erase(key); } else { std::cerr << command << ": warning: key \"" << key << "\" is not a valid identifier; ignoring\n"; } } break; } case '?': { if (optopt == 0 || optopt == -1) { const int failing_index = optind - 1; std::cerr << command << ": unknown long option"; if (failing_index >= 0 && failing_index < argc) { std::cerr << " \"" << argv[failing_index] << "\""; } std::cerr << std::endl; } else { const struct option* failing_long_option = lookup_long_option_by_id(long_options, optopt); if (failing_long_option == nullptr) { if (short_option_requires_argument(short_options, optopt)) { std::cerr << command << ": option \"-" << static_cast(optopt) << "\" requires an argument" << std::endl; } else { std::cerr << command << ": unknown option "; if (isprint(optopt)) { std::cerr << "\"-" << static_cast(optopt) << "\""; } else { std::cerr << "character 0x" << std::hex << optopt; } std::cerr << std::endl; } } else { assert(failing_long_option->has_arg == required_argument); std::cerr << command << ": option \"--" << failing_long_option->name << "\" requires an argument" << std::endl; } } std::cerr << "Try \"enblend --help\" for more information." << std::endl; exit(1); } default: std::cerr << command << ": internal error: unhandled command line option" << std::endl; exit(1); } } if (contains(optionSet, SaveMasksOption) && contains(optionSet, LoadMasksOption)) { std::cerr << command << ": options \"--load-masks\" and \"--save-masks\" are mutually exclusive" << std::endl; failed = true; } if (failed) { exit(1); } switch (print_only_task) { case VERSION_ONLY: #ifdef _MSC_VER // deinstall failure hook to catch errors in printVersion directly // so printVersion can run to end __pfnDliFailureHook2 = nullptr; #endif introspection::printVersion(argc, argv); break; // never reached case USAGE_ONLY: printUsage(false); break; // never reached case IMAGE_FORMATS_ONLY: introspection::printImageFormats(); break; // never reached case SIGNATURE_ONLY: introspection::printSignature(); break; // never reached case GLOBBING_ALGOS_ONLY: introspection::printGlobbingAlgos(); break; // never reached case SOFTWARE_COMPONENTS_ONLY: introspection::printSoftwareComponents(); break; // never reached case GPU_INFO_COMPONENTS_ONLY: #ifdef OPENCL std::cout << "Available, OpenCL-compatible platform(s) and their device(s)\n"; ocl::print_opencl_information(); ocl::print_gpu_preference(preferredGPUPlatform, preferredGPUDevice); exit(0); #else std::cerr << command << ": option \"--show-gpu-info\" is not implemented in this binary,\n" << command << ": because it was compiled without support for OpenCL" << std::endl; exit(1); #endif break; // never reached case PROCESS_COMPLETELY: break; default: NEVER_REACHED("switch control expression \"print_only_task\" out of range"); } StopAfterMaskGeneration = contains(optionSet, SaveMasksOption) && !contains(optionSet, OutputOption); warn_of_ineffective_options(optionSet); #ifdef OPENCL if (UseGPU) { initialize_gpu_subsystem(preferredGPUPlatform, preferredGPUDevice); } #endif // OPENCL return optind; } int main(int argc, char** argv) { #ifdef _MSC_VER // Make sure the FPU is set to rounding mode so that the lrint // functions in float_cast.h will work properly. // See changes in vigra numerictraits.hxx _controlfp(_RC_NEAR, _MCW_RC); // install failure hook for delayed loading of dll __pfnDliFailureHook2 = delayHookFailureFunc; #else fesetround(FE_TONEAREST); #endif #ifndef _WIN32 sigemptyset(&SigintMask); sigaddset(&SigintMask, SIGINT); struct sigaction action; action.sa_handler = sigint_handler; action.sa_flags = 0; sigemptyset(&(action.sa_mask)); sigaction(SIGINT, &action, nullptr); #else signal(SIGINT, sigint_handler); #endif if (atexit(cleanup_output) != 0) { std::cerr << command << ": warning: could not install cleanup routine\n"; } sig.initialize(); gsl_set_error_handler_off(); TIFFSetWarningHandler(tiff_warning); TIFFSetErrorHandler(tiff_error); //< layer-selector all-layers LayerSelection.set_selector(selector::find_by_id(selector::id_t::AllLayersId)->get()); if (!getopt_long_works_ok()) { std::cerr << command << ": cannot reliably parse command line; giving up\n"; exit(1); } int optind; try { optind = process_options(argc, argv); } catch (vigra::StdException& e) { std::cerr << command << ": error while processing command line options\n" << command << ": " << e.what() << std::endl; exit(1); } #ifdef OPENCL if (GPUContext && UseGPU) { GPU::StateProbabilities = ocl::create_function(GPUContext); GPU::DistanceTransform = ocl::create_function(GPUContext); if (BatchCompiler) { BatchCompiler->submit(GPU::StateProbabilities.get()); BatchCompiler->submit(GPU::DistanceTransform.get()); } } #endif enblend::TraceableFileNameList inputTraceableFileNameList; // Remaining parameters are input files. while (optind < argc) { enblend::TraceableFileNameList files; enblend::unfold_filename(files, std::string(argv[optind])); inputTraceableFileNameList.insert(inputTraceableFileNameList.end(), files.begin(), files.end()); optind++; } if (inputTraceableFileNameList.empty()) { std::cerr << command << ": no input files specified\n"; exit(1); } if (parameter::as_boolean("dump-global-variables", false)) { DUMP_GLOBAL_VARIABLES(); } sig.check(); for (enblend::TraceableFileNameList::iterator i = inputTraceableFileNameList.begin(); i != inputTraceableFileNameList.end(); ++i) { if (!enblend::can_open_file((*i)->filename())) { (*i)->unroll_trace(); exit(1); } if (!vigra::isImage((*i)->filename().c_str())) { std::cerr << command << ": cannot process \"" << (*i)->filename() << "\"; not recognized as an image\n" << command << ": info: possible causes:\n" << command << ": info: - An underlying image-processing library does not understand the\n" << command << ": info: particular compression, sub-format, format extension, ...\n" << command << ": info: - Enblend was not compiled with support for this format, which\n" << command << ": info: can be checked with \"" << command << " --show-image-formats\".\n" << command << ": info: - The image is corrupted or it is incomplete/truncated.\n" << command << ": info: - It really is not an image. Honesty, huh?\n"; (*i)->unroll_trace(); exit(1); } } LayerSelection.retrieve_image_information(inputTraceableFileNameList.begin(), inputTraceableFileNameList.end()); // List of info structures for each input image. std::list imageInfoList; std::list::iterator imageInfoIterator; bool isColor = false; std::string pixelType; TiffResolution resolution; vigra::ImageImportInfo::ICCProfile iccProfile; vigra::Rect2D inputUnion; int minDim = std::numeric_limits::max(); selector::layer_ordered_list_t viable_layers; selector::layer_ordered_list_t::const_iterator layer; unsigned layers = 0; // total number of layers in image file enblend::FileNameList inputFileNameList; enblend::TraceableFileNameList::iterator inputFileNameIterator = inputTraceableFileNameList.begin(); while (inputFileNameIterator != inputTraceableFileNameList.end()) { const std::string filename((*inputFileNameIterator)->filename()); vigra::ImageImportInfo* inputInfo = nullptr; try { vigra::ImageImportInfo info(filename.c_str()); if (layers == 0) { // OPTIMIZATION: call only once per file layers = info.numImages(); LayerSelection.set_selector((*inputFileNameIterator)->selector()); viable_layers.clear(); viable_layers = LayerSelection.viable_layers(filename); layer = viable_layers.begin(); #ifdef DEBUG_FILESPEC std::cout << "+ viable_layers(" << filename << ") are [ "; std::copy(viable_layers.begin(), viable_layers.end(), std::ostream_iterator(std::cout, " ")); std::cout << "]\n"; #endif } inputInfo = new vigra::ImageImportInfo(info); } catch (vigra::ContractViolation& exception) { std::cerr << command << ": cannot load image \"" << filename << "\"\n" << command << ": " << exception.what() << "\n"; if (enblend::maybe_response_file(filename)) { std::cerr << command << ": note: maybe you meant a response file and forgot the initial '" << RESPONSE_FILE_PREFIX_CHAR << "'?\n"; } exit(1); } assert(layer != viable_layers.end()); inputInfo->setImageIndex(*layer - 1); if (Verbose >= VERBOSE_LAYER_SELECTION) { std::cerr << command << ": info: layer selector \"" << LayerSelection.name() << "\" accepts\n" << command << ": info: layer " << *layer << " of " << layers << " in image \"" << filename << "\"\n"; } // Save this image info in the list. imageInfoList.push_back(inputInfo); inputFileNameList.push_back(filename); if (Verbose >= VERBOSE_INPUT_IMAGE_INFO_MESSAGES) { std::cerr << command << ": info: input image \"" << (*inputFileNameIterator)->filename() << "\" " << *layer << '/' << layers << ' '; if (inputInfo->isColor()) { std::cerr << "RGB "; } if (!inputInfo->getICCProfile().empty()) { std::cerr << "ICC "; } std::cerr << inputInfo->getPixelType() << " position=" << inputInfo->getPosition().x << "x" << inputInfo->getPosition().y << " " << "size=" << inputInfo->width() << "x" << inputInfo->height() << std::endl; } if (inputInfo->numExtraBands() < 1) { // Complain about lack of alpha channel. std::cerr << command << ": input image \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << " does not have an alpha channel\n"; (*inputFileNameIterator)->unroll_trace(); exit(1); } // Get input image's position and size. vigra::Rect2D imageROI(vigra::Point2D(inputInfo->getPosition()), vigra::Size2D(inputInfo->width(), inputInfo->height())); if (inputFileNameIterator == inputTraceableFileNameList.begin()) { // First input image minDim = std::min(inputInfo->width(), inputInfo->height()); inputUnion = imageROI; isColor = inputInfo->isColor(); pixelType = inputInfo->getPixelType(); resolution = TiffResolution(inputInfo->getXResolution(), inputInfo->getYResolution()); iccProfile = inputInfo->getICCProfile(); if (!iccProfile.empty()) { InputProfile = cmsOpenProfileFromMem(iccProfile.data(), iccProfile.size()); if (InputProfile == nullptr) { std::cerr << std::endl << command << ": error parsing ICC profile data from file \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << std::endl; (*inputFileNameIterator)->unroll_trace(); exit(1); } } } else { // Second and later images inputUnion |= imageROI; if (isColor != inputInfo->isColor()) { std::cerr << command << ": input image \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << " is " << (inputInfo->isColor() ? "color" : "grayscale") << "\n" << command << ": but previous images are " << (isColor ? "color" : "grayscale") << std::endl; (*inputFileNameIterator)->unroll_trace(); exit(1); } if (pixelType != inputInfo->getPixelType()) { std::cerr << command << ": input image \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << " has pixel type " << inputInfo->getPixelType() << ",\n" << command << ": but previous images have pixel type " << pixelType << std::endl; (*inputFileNameIterator)->unroll_trace(); exit(1); } if (resolution != TiffResolution(inputInfo->getXResolution(), inputInfo->getYResolution())) { std::cerr << command << ": info: input image \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << " has resolution " << inputInfo->getXResolution() << " dpi x " << inputInfo->getYResolution() << " dpi,\n" << command << ": info: but first image has resolution " << resolution.x << " dpi x " << resolution.y << " dpi" << std::endl; (*inputFileNameIterator)->unroll_trace(); } if (iccProfile != inputInfo->getICCProfile()) { vigra::ImageImportInfo::ICCProfile mismatchProfile(inputInfo->getICCProfile()); cmsHPROFILE newProfile = nullptr; if (!mismatchProfile.empty()) { newProfile = cmsOpenProfileFromMem(mismatchProfile.data(), mismatchProfile.size()); if (newProfile == nullptr) { std::cerr << std::endl << command << ": error parsing ICC profile data from file \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << std::endl; (*inputFileNameIterator)->unroll_trace(); exit(1); } } if (InputProfile == nullptr || newProfile == nullptr || enblend::profileDescription(InputProfile) != enblend::profileDescription(newProfile)) { const std::string category(BlendColorspace <= IdentitySpace ? "warning" : "info"); std::cerr << std::endl << command << ": " << category << ": input image \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << "\n"; (*inputFileNameIterator)->unroll_trace(); std::cerr << command << ": " << category << ": has "; if (newProfile) { std::cerr << "ICC profile \"" << enblend::profileDescription(newProfile) << "\",\n"; } else { std::cerr << "no ICC profile,\n"; } std::cerr << command << ": " << category << ": but first image has "; if (InputProfile) { std::cerr << "ICC profile \"" << enblend::profileDescription(InputProfile) << "\";\n"; } else { std::cerr << "no ICC profile;\n"; } if (BlendColorspace <= IdentitySpace) { std::cerr << command << ": " << category << ": blending images with different color spaces\n" << command << ": " << category << ": may have unexpected results\n"; } } } if (inputInfo->width() < minDim) { minDim = inputInfo->width(); } if (inputInfo->height() < minDim) { minDim = inputInfo->height(); } } ++layer; if (layer == viable_layers.end()) { #ifdef DEBUG_FILESPEC std::cout << "+ next image\n"; #endif layers = 0; ++inputFileNameIterator; } else { #ifdef DEBUG_FILESPEC std::cout << "+ next layer\n"; #endif // We are about to process the next layer in the _same_ // image. The imageInfoList already has been updated, but // inputTraceableFileNameList still lacks the filename. inputTraceableFileNameList.insert(inputFileNameIterator, (*inputFileNameIterator)->clone()); } } // Check that more than one input file was given. if (imageInfoList.size() <= 1) { const size_t n = inputTraceableFileNameList.size(); const size_t m = imageInfoList.size(); if (n > m) { std::cerr << command << ": warning: selector has rejected " << n - m << " out of " << n << " images\n"; } switch (m) { case 0: std::cerr << command << ": no input images given\n"; exit(1); break; case 1: std::cerr << command << ": warning: only one input image given;\n" << command << ": note: Enblend needs two or more overlapping input images in order to do\n" << command << ": note: blending calculations. The output will be the same as the input.\n"; break; } } if (resolution == TiffResolution()) { std::cerr << command << ": warning: no usable resolution found in first image \"" << (*inputTraceableFileNameList.begin())->filename() << "\";\n" << command << ": note: Enblend will assume " << DEFAULT_TIFF_RESOLUTION << " dpi\n"; ImageResolution = TiffResolution(DEFAULT_TIFF_RESOLUTION, DEFAULT_TIFF_RESOLUTION); } else { ImageResolution = resolution; } // Switch to fine mask, if the smallest coarse mask would be less // than 64 pixels wide or high. if (minDim / 8 < 64 && CoarseMask) { std::cerr << command << ": warning: input images too small for coarse mask\n" << command << ": note: switching to fine mask" << std::endl; CoarseMask = false; if (MainAlgorithm == GraphCut) { std::cerr << command << ": warning: fine mask combined with graphcut incompatible with mask optimization\n" << command << ": note: defaulting to no optimization" << std::endl; OptimizeMask = false; } } if (MaskVectorizeDistance.value() == 0) { MaskVectorizeDistance.set_percentage(false); MaskVectorizeDistance.set_value(CoarseMask ? coarseMaskVectorizeDistance : fineMaskVectorizeDistance); } // Create the Info for the output file. vigra::ImageExportInfo outputImageInfo(OutputFileName.c_str()); if (!StopAfterMaskGeneration) { OutputIsValid = false; // Make sure that inputUnion is at least as big as given by the -f paramater. if (OutputSizeGiven) { inputUnion |= vigra::Rect2D(OutputOffsetXCmdLine, OutputOffsetYCmdLine, OutputOffsetXCmdLine + OutputWidthCmdLine, OutputOffsetYCmdLine + OutputHeightCmdLine); } if (!OutputCompression.empty()) { outputImageInfo.setCompression(OutputCompression.c_str()); } // If not overridden by the command line, the pixel type of the // output image is the same as the input images'. If the pixel // type is not supported by the output format, replace it with the // best match. { const std::string outputFileType = enblend::getFileType(OutputFileName); const std::string neededPixelType = OutputPixelType.empty() ? std::string(pixelType) : OutputPixelType; const std::string bestPixelType = enblend::bestPixelType(outputFileType, neededPixelType); if (neededPixelType != bestPixelType) { std::cerr << command << ": warning: " << (OutputPixelType.empty() ? "deduced" : "requested") << " output pixel type is \"" << neededPixelType << "\", but image type \"" << outputFileType << "\"\n" << command << ": warning: supports \"" << bestPixelType << "\" at best; will use \"" << bestPixelType << "\"" << std::endl; } outputImageInfo.setPixelType(bestPixelType.c_str()); pixelType = enblend::maxPixelType(pixelType, bestPixelType); } // Set the output image ICC profile outputImageInfo.setICCProfile(iccProfile); if (BlendColorspace == UndeterminedColorspace && !(iccProfile.empty() || enblend::isFloatingPoint(pixelType))) { BlendColorspace = CIELUV; } if (BlendColorspace == CIECAM || BlendColorspace == CIELAB || BlendColorspace == CIELUV) { if (enblend::isFloatingPoint(pixelType)) { std::cerr << command << ": warning: blend color space for floating-point images is not \"identity\"" << std::endl; } if (InputProfile == nullptr) { std::cerr << command << ": warning: input images do not have ICC profiles;\n"; if (FallbackProfile == nullptr) { std::cerr << command << ": warning: assuming sRGB profile" << std::endl; InputProfile = cmsCreate_sRGBProfile(); } else { std::cerr << command << ": warning: using fallback profile \"" << enblend::profileDescription(FallbackProfile) << "\"" << std::endl; InputProfile = FallbackProfile; FallbackProfile = nullptr; // avoid double freeing } } XYZProfile = cmsCreateXYZProfile(); const unsigned input_profile_type = enblend::profileChannels(InputProfile) > 1 ? TYPE_RGB_DBL : TYPE_GRAY_DBL; InputToXYZTransform = cmsCreateTransform(InputProfile, input_profile_type, XYZProfile, TYPE_XYZ_DBL, RENDERING_INTENT_FOR_BLENDING, TRANSFORMATION_FLAGS_FOR_BLENDING); if (InputToXYZTransform == nullptr) { std::cerr << command << ": error building color transform from \"" << enblend::profileName(InputProfile) << " " << enblend::profileDescription(InputProfile) << "\" to XYZ space" << std::endl; exit(1); } XYZToInputTransform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL, InputProfile, input_profile_type, RENDERING_INTENT_FOR_BLENDING, TRANSFORMATION_FLAGS_FOR_BLENDING); if (XYZToInputTransform == nullptr) { std::cerr << command << ": error building color transform from XYZ space to \"" << enblend::profileName(InputProfile) << " " << enblend::profileDescription(InputProfile) << "\"" << std::endl; exit(1); } // P2 Viewing Conditions: D50, 500 lumens ViewingConditions.whitePoint.X = XYZ_SCALE * cmsD50_XYZ()->X; ViewingConditions.whitePoint.Y = XYZ_SCALE * cmsD50_XYZ()->Y; ViewingConditions.whitePoint.Z = XYZ_SCALE * cmsD50_XYZ()->Z; ViewingConditions.Yb = 20.0; ViewingConditions.La = 31.83; ViewingConditions.surround = AVG_SURROUND; ViewingConditions.D_value = 1.0; CIECAMTransform = cmsCIECAM02Init(nullptr, &ViewingConditions); if (!CIECAMTransform) { std::cerr << std::endl << command << ": error initializing CIECAM02 transform" << std::endl; exit(1); } cmsCIExyY white_point; if (cmsIsTag(InputProfile, cmsSigMediaWhitePointTag)) { cmsXYZ2xyY(&white_point, (const cmsCIEXYZ*) cmsReadTag(InputProfile, cmsSigMediaWhitePointTag)); if (Verbose >= VERBOSE_COLOR_CONVERSION_MESSAGES) { double temperature; cmsTempFromWhitePoint(&temperature, &white_point); std::cerr << command << ": info: using white point of input profile at " << temperature << "K" << std::endl; } } else { memcpy(&white_point, cmsD50_xyY(), sizeof(cmsCIExyY)); if (Verbose >= VERBOSE_COLOR_CONVERSION_MESSAGES) { double temperature; cmsTempFromWhitePoint(&temperature, &white_point); std::cerr << command << ": info: falling back to predefined (D50) white point at " << temperature << "K" << std::endl; } } LabProfile = cmsCreateLab2Profile(&white_point); InputToLabTransform = cmsCreateTransform(InputProfile, input_profile_type, LabProfile, TYPE_Lab_DBL, RENDERING_INTENT_FOR_BLENDING, TRANSFORMATION_FLAGS_FOR_BLENDING); if (!InputToLabTransform) { std::cerr << command << ": error building color transform from \"" << enblend::profileName(InputProfile) << " " << enblend::profileDescription(InputProfile) << "\" to Lab space" << std::endl; exit(1); } LabToInputTransform = cmsCreateTransform(LabProfile, TYPE_Lab_DBL, InputProfile, input_profile_type, RENDERING_INTENT_FOR_BLENDING, TRANSFORMATION_FLAGS_FOR_BLENDING); if (!LabToInputTransform) { std::cerr << command << ": error building color transform from Lab space to \"" << enblend::profileName(InputProfile) << " " << enblend::profileDescription(InputProfile) << "\"" << std::endl; exit(1); } } else { if (FallbackProfile != nullptr) { std::cerr << command << ": warning: blending in identity space; option \"--fallback-profile\" has no effect" << std::endl; } } // The size of the output image. if (Verbose >= VERBOSE_INPUT_UNION_SIZE_MESSAGES) { std::cerr << command << ": info: output image size: " << inputUnion << std::endl; } // Set the output image position and resolution. outputImageInfo.setXResolution(ImageResolution.x); outputImageInfo.setYResolution(ImageResolution.y); outputImageInfo.setPosition(inputUnion.upperLeft()); // Sanity check on the output image file. try { // This seems to be a reasonable way to check if // the output file is going to work after blending // is done. encoder(outputImageInfo); } catch (vigra::StdException & e) { std::cerr << std::endl << command << ": error opening output file \"" << OutputFileName << "\";\n" << command << ": " << e.what() << std::endl; exit(1); } if (!OutputPixelType.empty()) { pixelType = enblend::maxPixelType(pixelType, OutputPixelType); } } // Invoke templatized blender. try { if (isColor) { if (pixelType == "UINT8") enblend::enblendMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); #ifndef DEBUG_8BIT_ONLY else if (pixelType == "UINT16") enblend::enblendMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "INT16") enblend::enblendMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "UINT32") enblend::enblendMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "INT32") enblend::enblendMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "FLOAT") enblend::enblendMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "DOUBLE") enblend::enblendMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); #endif else { std::cerr << command << ": RGB images with pixel type \"" << pixelType << "\" are not supported" << std::endl; exit(1); } } else { if (pixelType == "UINT8") enblend::enblendMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); #ifndef DEBUG_8BIT_ONLY else if (pixelType == "UINT16") enblend::enblendMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "INT16") enblend::enblendMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "UINT32") enblend::enblendMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "INT32") enblend::enblendMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "FLOAT") enblend::enblendMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "DOUBLE") enblend::enblendMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); #endif else { std::cerr << command << ": black&white images with pixel type \"" << pixelType << "\" are not supported" << std::endl; exit(1); } } for (auto x : imageInfoList) { delete x; } for (auto x : inputTraceableFileNameList) { delete x; } } catch (std::bad_alloc& e) { std::cerr << std::endl << command << ": out of memory\n" << command << ": " << e.what() << std::endl; exit(1); } catch (vigra::StdException& e) { std::cerr << std::endl << command << ": an exception occured\n" << command << ": " << e.what() << std::endl; exit(1); } #ifdef OPENCL delete GPUContext; #endif // OPENCL if (FallbackProfile) {cmsCloseProfile(FallbackProfile);} if (LabProfile) {cmsCloseProfile(LabProfile);} if (InputToLabTransform) {cmsCIECAM02Done(InputToLabTransform);} if (LabToInputTransform) {cmsCIECAM02Done(LabToInputTransform);} if (CIECAMTransform) {cmsCIECAM02Done(CIECAMTransform);} if (InputToXYZTransform) {cmsDeleteTransform(InputToXYZTransform);} if (XYZToInputTransform) {cmsDeleteTransform(XYZToInputTransform);} if (XYZProfile) {cmsCloseProfile(XYZProfile);} if (InputProfile) {cmsCloseProfile(InputProfile);} // Success. return 0; } enblend-enfuse-4.2/src/DefaultSig.pm0000644000175000017500000001025512663540270014356 00000000000000# name: DefaultSig.pm # synopsis: base class for signature generation # author: Dr. Christoph L. Spiel # perl version: 5.10.0 # This file is part of Enblend. # Licence details can be found in the file COPYING. package DefaultSig; use strict; use warnings; use English; use Sys::Hostname; our %HAVE_MODULE; BEGIN { foreach my $module (qw(Time::Zone)) { eval "use $module ()"; # import, but keep module's original name space for clarity $HAVE_MODULE{$module} = $EVAL_ERROR eq ''; } } sub new { my ($class, $do_use_gmt) = @_; my $self = {}; bless $self, $class; $self->_initialize($do_use_gmt); return $self; } sub _initialize { my ($self, $do_use_gmt) = @_; $self->{USERNAME} = $self->_real_user_name(); $self->{HOSTNAME} = $self->_clean_hostname(); $self->use_gmt($do_use_gmt); $self->update_date_and_time(); } sub get_username {my $self = shift; return $self->{USERNAME}} sub get_hostname {my $self = shift; return $self->{HOSTNAME}} sub get_date {my $self = shift; return $self->{DATE}} sub get_time {my $self = shift; return $self->{TIME}} sub is_using_gmt {my $self = shift; return $self->{USE_GMT} != 0} sub use_gmt { my ($self, $x) = @_; $self->{USE_GMT} = $x ? ($x == 0 ? 0 : 1) : 0; } # Answer a formatted date string based on the current date. # # 1 <= $day_of_month <= 31 # 1 <= $month <= 12 # 1900 <= $year # 0 <= $day_of_week <= 7 # $weekday: Mon, Tue, ... # $monthname: Jan, Feb, ... sub format_date { my ($self, $day_of_month, $month, $year, $day_of_week, $weekday, $monthname) = @_; return sprintf("%s, %s %02u %u", $weekday, $monthname, $day_of_month, $year); } # Answer a formatted time string based on the current time. sub format_time { my ($self, $second, $minute, $hour) = @_; my $time = sprintf("%02u:%02u:%02u", $hour, $minute, $second); if ($self->is_using_gmt()) { $time .= " GMT"; } else { if ($HAVE_MODULE{'Time::Zone'}) { $time .= sprintf(" GMT%+d", Time::Zone::tz_offset($ENV{'TZ'}) / 3600.0); # alternatively: # $time .= " " . Time::Zone::tz_name($ENV{'TZ'}); } } return $time; } sub weekdays {my $self = shift; return [qw(Sun Mon Tue Wed Thu Fri Sat)]} sub monthnames {my $self = shift; return [qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)]} # Update date and time fields simultaneously to get a consistent time # stamp. If is_using_gmt() use GMT instead of the local time, which # may be defined by the TZ environment variable. sub update_date_and_time { my $self = shift; my ($second, $minute, $hour, $day_of_month, $month, $year, $day_of_week) = $self->is_using_gmt() ? gmtime : localtime; $self->{DATE} = $self->format_date($day_of_month, $month, $year + 1900, $day_of_week, $self->weekdays->[$day_of_week], $self->monthnames->[$month]); $self->{TIME} = $self->format_time($second, $minute, $hour); } sub signature { my $self = shift; return sprintf("Compiled on %s by %s on %s, %s.", $self->get_hostname(), $self->get_username(), $self->get_date(), $self->get_time()); } sub _login_name { my $self = shift; return (getlogin or 'anonymous'); } # Try to derive the real user name from Perl's built-in user id. # Answer the user's login name if we do not find a real name. sub _real_user_name { my $self = shift; if ($OSNAME eq 'MSWin32') { return $self->_login_name(); } else { my ($login_name, undef, undef, undef, undef, undef, $gcos) = getpwuid $REAL_USER_ID; if ($gcos) { my ($real_user_name) = split m/,/, $gcos; return $real_user_name if $real_user_name; } if ($login_name) { return $login_name; } else { return $self->_login_name(); } } } sub _clean_hostname { my $self = shift; my $hostname = hostname(); if ($OSNAME =~ m/MacOS/) { $hostname =~ s/^(.*?)[-.].*$/$1/; } return $hostname; } 1; enblend-enfuse-4.2/src/enblend.10000644000175000017500000001421212676432657013474 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.4. .TH ENBLEND "1" "March 2016" "enblend 4.2" "User Commands" .SH NAME enblend \- manual page for enblend 4.2 .SH SYNOPSIS .B enblend [\fI\,options\/\fR] [\fI\,--output=IMAGE\/\fR] \fI\,INPUT\/\fR... .SH DESCRIPTION Blend INPUT images into a single IMAGE. .PP INPUT... are image filenames or response filenames. Response filenames start with an "@" character. .SH OPTIONS .SS "Common options:" .TP \fB\-l\fR, \fB\-\-levels\fR=\fI\,LEVELS\/\fR limit number of blending LEVELS to use (1 to 29); negative number of LEVELS decreases maximum; "auto" restores the default automatic maximization .TP \fB\-o\fR, \fB\-\-output\fR=\fI\,FILE\/\fR write output to FILE; default: "a.tif" .TP \fB\-v\fR, \fB\-\-verbose\fR[=\fI\,LEVEL\/\fR] verbosely report progress; repeat to increase verbosity or directly set to LEVEL .TP \fB\-\-compression\fR=\fI\,COMPRESSION\/\fR set compression of output image to COMPRESSION, where COMPRESSION is: "deflate", "jpeg", "lzw", "none", "packbits", for TIFF files and 0 to 100, or "jpeg", "jpeg\-arith" for JPEG files, where "jpeg" and "jpeg\-arith" accept a compression level .SS "Advanced options:" .TP \fB\-\-blend\-colorspace\fR=\fI\,COLORSPACE\/\fR force COLORSPACE for blending operations; Enblend uses "CIELUV" for images with ICC\-profile and "IDENTITY" for those without and also for all floating\-point images; other available blend color spaces are "CIELAB" and "CIECAM" .TP \fB\-c\fR, \fB\-\-ciecam\fR use CIECAM02 to blend colors; disable with "\-\-no\-ciecam"; note that this option will be withdrawn in favor of "\-\-blend\-colorspace" .TP \fB\-d\fR, \fB\-\-depth\fR=\fI\,DEPTH\/\fR set the number of bits per channel of the output image, where DEPTH is "8", "16", "32", "r32", or "r64" .TP \fB\-f\fR WIDTHxHEIGHT[+xXOFFSET+yYOFFSET] manually set the size and position of the output image; useful for cropped and shifted input TIFF images, such as those produced by Nona .TP \fB\-g\fR associated\-alpha hack for Gimp (before version 2) and Cinepaint .TP \fB\-w\fR, \fB\-\-wrap\fR[=\fI\,MODE\/\fR] wrap around image boundary, where MODE is "none", "horizontal", "vertical", or "both"; default: none; without argument the option selects horizontal wrapping .SS "Mask generation options:" .TP \fB\-\-coarse\-mask\fR[=\fI\,FACTOR\/\fR] shrink overlap regions by FACTOR to speedup mask generation; this is the default; if omitted FACTOR defaults to 8 .TP \fB\-\-fine\-mask\fR generate mask at full image resolution; use e.g. if overlap regions are very narrow .TP \fB\-\-optimize\fR turn on mask optimization; this is the default; disable with "\-\-no\-optimize" .TP \fB\-\-save\-masks\fR[=\fI\,TEMPLATE\/\fR] save generated masks in TEMPLATE; default: "mask\-%n.tif"; conversion chars: "%i": mask index, "%n": mask number, "%p": full path, "%d": dirname, "%b": basename, "%f": filename, "%e": extension; lowercase characters refer to input images uppercase to the output image .TP \fB\-\-load\-masks\fR[=\fI\,TEMPLATE\/\fR] use existing masks in TEMPLATE instead of generating them; same template characters as "\-\-save\-masks"; default: "mask\-%n.tif" .TP \fB\-\-visualize\fR[=\fI\,TEMPLATE\/\fR] save results of optimizer in TEMPLATE; same template characters as "\-\-save\-masks"; default: "vis\-%n.tif" .SS "Expert options:" .TP \fB\-a\fR, \fB\-\-pre\-assemble\fR pre\-assemble non\-overlapping images; negate with "\-\-no\-pre\-assemble" .TP \fB\-x\fR checkpoint partial results .TP \fB\-\-fallback\-profile\fR=\fI\,PROFILE\-FILE\/\fR use the ICC profile from PROFILE\-FILE instead of sRGB .TP \fB\-\-layer\-selector\fR=\fI\,ALGORITHM\/\fR set the layer selector ALGORITHM; default: "all\-layers"; available algorithms are: "all\-layers": select all layers in any image; "first\-layer": select only first layer in each (multi\-)layer image; "last\-layer": select only last layer in each (multi\-)layer image; "largest\-layer": select largest layer in each (multi\-)layer image; "no\-layer": do not select any layer from any image; .TP \fB\-\-parameter\fR=\fI\,KEY1[=VALUE1][\/\fR:KEY2[=VALUE2][:...]] set one or more KEY\-VALUE pairs .SS "Expert mask generation options:" .TP \fB\-\-primary\-seam\-generator\fR=\fI\,ALGORITHM\/\fR use main seam finder ALGORITHM, where ALGORITHM is "nearest\-feature\-transform" or "graph\-cut"; default: "graph\-cut" .TP \fB\-\-image\-difference\fR=\fI\,ALGORITHM[\/\fR:LUMINANCE\-WEIGHT[:CHROMINANCE\-WEIGHT]] use ALGORITHM for calculation of the difference image, where ALGORITHM is "max\-hue\-luminance" or "delta\-e"; LUMINANCE\-WEIGHT and CHROMINANCE\-WEIGHT define the weights of lightness and color; default: delta\-e:1:1 .TP \fB\-\-optimizer\-weights\fR=\fI\,DISTANCE\-WEIGHT[\/\fR:MISMATCH\-WEIGHT] set the optimizer's weigths for distance and mismatch; default: 8:1 .TP \fB\-\-mask\-vectorize\fR=\fI\,LENGTH\/\fR set LENGTH of single seam segment; append "%" for relative value; defaults: 4 for coarse masks and 20 for fine masks .TP \fB\-\-anneal\fR=\fI\,TAU[\/\fR:DELTAE\-MAX[:DELTAE\-MIN[:K\-MAX]]] set annealing parameters of optimizer strategy 1; defaults: 0.75:7000:5:32 .TP \fB\-\-dijkstra\fR=\fI\,RADIUS\/\fR set search RADIUS of optimizer strategy 2; default: 25 pixels .SS "Information options:" .TP \fB\-h\fR, \fB\-\-help\fR print this help message and exit .TP \fB\-V\fR, \fB\-\-version\fR output version information and exit .TP \fB\-\-show\-globbing\-algorithms\fR show all globbing algorithms .TP \fB\-\-show\-image\-formats\fR show all recognized image formats and their filename extensions .TP \fB\-\-show\-signature\fR show who compiled the binary when and on which machine .TP \fB\-\-show\-software\-components\fR show the software components with which Enblend was compiled .PP Enblend accepts arguments to any option in uppercase as well as in lowercase letters. .SH AUTHOR Written by Andrew Mihal, Christoph Spiel and others. .SH "REPORTING BUGS" Report bugs at . .SH COPYRIGHT Copyright \(co 2004\-2009 Andrew Mihal. .br Copyright \(co 2009\-2016 Christoph Spiel. .PP License GPLv2+: GNU GPL version 2 or later .br This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. enblend-enfuse-4.2/src/enblend.h0000644000175000017500000005540612641706002013551 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ENBLEND_H__ #define __ENBLEND_H__ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "rect2d.hxx" #include "common.h" #include "opencl.h" #include "openmp_def.h" #include "openmp_vigra.h" #include "numerictraits.h" #include "fixmath.h" #include "assemble.h" #include "blend.h" #include "bounds.h" #include "mask.h" #include "pyramid.h" namespace enblend { /** Enblend's main blending loop. Templatized to handle different image types. */ template void enblendMain(const FileNameList& anInputFileNameList, const std::list& anImageInfoList, vigra::ImageExportInfo& anOutputImageInfo, vigra::Rect2D& anInputUnion) { typedef typename EnblendNumericTraits::ImagePixelComponentType ImagePixelComponentType; typedef typename EnblendNumericTraits::ImageType ImageType; typedef typename EnblendNumericTraits::AlphaPixelType AlphaPixelType; typedef typename EnblendNumericTraits::AlphaType AlphaType; typedef typename EnblendNumericTraits::MaskPixelType MaskPixelType; typedef typename EnblendNumericTraits::MaskType MaskType; typedef typename EnblendNumericTraits::ImagePyramidPixelType ImagePyramidPixelType; typedef typename EnblendNumericTraits::ImagePyramidType ImagePyramidType; typedef typename EnblendNumericTraits::MaskPyramidPixelType MaskPyramidPixelType; typedef typename EnblendNumericTraits::MaskPyramidType MaskPyramidType; enum {ImagePyramidIntegerBits = EnblendNumericTraits::ImagePyramidIntegerBits}; enum {ImagePyramidFractionBits = EnblendNumericTraits::ImagePyramidFractionBits}; enum {MaskPyramidIntegerBits = EnblendNumericTraits::MaskPyramidIntegerBits}; enum {MaskPyramidFractionBits = EnblendNumericTraits::MaskPyramidFractionBits}; typedef typename EnblendNumericTraits::SKIPSMImagePixelType SKIPSMImagePixelType; typedef typename EnblendNumericTraits::SKIPSMAlphaPixelType SKIPSMAlphaPixelType; typedef typename EnblendNumericTraits::SKIPSMMaskPixelType SKIPSMMaskPixelType; std::list imageInfoList(anImageInfoList); // Create the initial black image. vigra::Rect2D blackBB; std::pair blackPair = assemble(imageInfoList, anInputUnion, blackBB); if (Checkpoint) { checkpoint(blackPair, anOutputImageInfo); } // mem usage before = 0 // mem xsection = OneAtATime: anInputUnion*imageValueType + anInputUnion*AlphaValueType // !OneAtATime: 2*anInputUnion*imageValueType + 2*anInputUnion*AlphaValueType // mem usage after = anInputUnion*ImageValueType + anInputUnion*AlphaValueType const unsigned numberOfImages = imageInfoList.size(); // Main blending loop. unsigned m = 0; FileNameList::const_iterator inputFileNameIterator(anInputFileNameList.begin()); while (!imageInfoList.empty()) { // Create the white image. vigra::Rect2D whiteBB; std::pair whitePair = assemble(imageInfoList, anInputUnion, whiteBB); // mem usage before = anInputUnion*ImageValueType + anInputUnion*AlphaValueType // mem xsection = OneAtATime: anInputUnion*imageValueType + anInputUnion*AlphaValueType // !OneAtATime: 2*anInputUnion*imageValueType + 2*anInputUnion*AlphaValueType // mem usage after = 2*anInputUnion*ImageValueType + 2*anInputUnion*AlphaValueType // Union bounding box of whiteImage and blackImage. vigra::Rect2D uBB = blackBB | whiteBB; if (Verbose >= VERBOSE_UBB_MESSAGES) { std::cerr << command << ": info: image union bounding box: " << uBB << std::endl; } // Intersection bounding box of whiteImage and blackImage. vigra::Rect2D iBB = blackBB & whiteBB; bool iBBValid = !iBB.isEmpty(); if (Verbose >= VERBOSE_IBB_MESSAGES) { std::cerr << command << ": info: image intersection bounding box: "; if (iBBValid) { std::cerr << iBB; } else { std::cerr << "(no intersection)"; } std::cerr << std::endl; } // Determine what kind of overlap we have. const Overlap overlap = inspectOverlap(vigra_ext::apply(uBB, srcImageRange(*(blackPair.second))), vigra_ext::apply(uBB, srcImage(*(whitePair.second)))); // If white image is redundant, skip it and go to next images. if (overlap == CompleteOverlap) { // White image is redundant. delete whitePair.first; delete whitePair.second; std::cerr << command << ": warning: some images are redundant and will not be blended\n" << command << ": note: usually this means that at least one of the images\n" << command << ": note: does not belong to the set" << std::endl; continue; } else if (overlap == NoOverlap && ExactLevels == 0) { // Images do not actually overlap. std::cerr << command << ": warning: images do not overlap; they will be combined without blending\n" << command << ": note: usually this means that at least one of these images does not\n" << command << ": note: belong to the set or the order of the images given at the\n" << command << ": note: command line is wrong; sometimes passing option\n" << command << ": note: \"--pre-assemble\" resolves the problem; in rare cases using\n" << command << ": note: option \"--levels=NUMBER\" to force blending with a certain\n" << command << ": note: NUMBER of levels can help, too" << std::endl; // Copy white image into black image verbatim. #ifdef OPENMP omp::scoped_nested(true); omp::scoped_dynamic(true); #pragma omp parallel { #pragma omp single nowait { #endif vigra::omp::copyImageIf(srcImageRange(*(whitePair.first)), maskImage(*(whitePair.second)), destImage(*(blackPair.first))); vigra::omp::copyImageIf(srcImageRange(*(whitePair.second)), maskImage(*(whitePair.second)), destImage(*(blackPair.second))); #ifdef OPENMP } // omp single } // omp parallel #endif delete whitePair.first; delete whitePair.second; // Checkpoint results. if (Checkpoint) { if (Verbose >= VERBOSE_CHECKPOINTING_MESSAGES) { std::cerr << command << ": info: "; if (imageInfoList.empty()) { std::cerr << "writing final output" << std::endl; } else { std::cerr << "checkpointing" << std::endl; } } checkpoint(blackPair, anOutputImageInfo); } blackBB = uBB; continue; } // Estimate memory requirements. if (Verbose >= VERBOSE_MEMORY_ESTIMATION_MESSAGES) { long long bytes = 0; // Input images bytes += 2 * uBB.area() * sizeof(ImagePixelType); // Input alpha channels bytes += 2 * uBB.area() * sizeof(AlphaPixelType); // Mem used during mask generation: long long nftBytes = 0; if (LoadMasks) { nftBytes = 0; } else if (CoarseMask) { nftBytes = 2 * 1/8 * uBB.area() * sizeof(MaskPixelType) + 2 * 1/8 * uBB.area() * sizeof(vigra::UInt32); } else { nftBytes = 2 * uBB.area() * sizeof(MaskPixelType) + 2 * uBB.area() * sizeof(vigra::UInt32); } long long optBytes = 0; if (LoadMasks) { optBytes = 0; } else if (!OptimizeMask) { optBytes = 0; } else if (CoarseMask) { optBytes = 1/2 * iBB.area() * sizeof(vigra::UInt8); } else { optBytes = iBB.area() * sizeof(vigra::UInt8); } if (VisualizeSeam) { optBytes *= 2; } const long long bytesDuringMask = bytes + std::max(nftBytes, optBytes); const long long bytesAfterMask = bytes + uBB.area() * sizeof(MaskPixelType); bytes = std::max(bytesDuringMask, bytesAfterMask); std::cerr << command << ": info: estimated space required for mask generation: " << static_cast(ceil(bytes / 1000000.0)) << "MB" << std::endl; } // Create the blend mask. const bool wraparoundForMask = WrapAround != OpenBoundaries && uBB.width() == anInputUnion.width(); MaskType* mask = createMask(whitePair.first, blackPair.first, whitePair.second, blackPair.second, uBB, iBB, wraparoundForMask, numberOfImages, inputFileNameIterator, m); // Calculate bounding box of seam line. vigra::Rect2D mBB; maskBounds(mask, uBB, mBB); if (SaveMasks) { const std::string maskFilename = enblend::expandFilenameTemplate(SaveMaskTemplate, numberOfImages, *inputFileNameIterator, OutputFileName, m); if (maskFilename == *inputFileNameIterator) { std::cerr << command << ": will not overwrite input image \"" << *inputFileNameIterator << "\" with mask file" << std::endl; exit(1); } else if (maskFilename == OutputFileName) { std::cerr << command << ": will not overwrite output image \"" << OutputFileName << "\" with mask file" << std::endl; exit(1); } else { if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << command << ": info: saving mask \"" << maskFilename << "\"" << std::endl; } vigra::ImageExportInfo maskInfo(maskFilename.c_str()); maskInfo.setXResolution(ImageResolution.x); maskInfo.setYResolution(ImageResolution.y); maskInfo.setPosition(uBB.upperLeft()); maskInfo.setCompression(MASK_COMPRESSION); exportImage(srcImageRange(*mask), maskInfo); } } // mem usage here = MaskType*ubb + // 2*anInputUnion*ImageValueType + // 2*anInputUnion*AlphaValueType // Calculate ROI bounds and number of levels from mBB. // ROI bounds must be at least mBB but not to extend uBB. vigra::Rect2D roiBB; const unsigned int numLevels = roiBounds(anInputUnion, iBB, mBB, uBB, roiBB, wraparoundForMask); const bool wraparoundForBlend = WrapAround != OpenBoundaries && roiBB.width() == anInputUnion.width(); if (StopAfterMaskGeneration) { vigra::copyImageIf(vigra_ext::apply(uBB, srcImageRange(*(whitePair.first))), maskImage(*mask), vigra_ext::apply(uBB, destImage(*(blackPair.first)))); vigra::initImageIf(vigra_ext::apply(whiteBB, destImageRange(*(blackPair.second))), vigra_ext::apply(whiteBB, maskImage(*(whitePair.second))), vigra::NumericTraits::max()); delete whitePair.first; delete whitePair.second; blackBB = uBB; ++m; ++inputFileNameIterator; continue; } // Estimate memory requirements for this blend iteration if (Verbose >= VERBOSE_MEMORY_ESTIMATION_MESSAGES) { // Maximum utilization is when all three pyramids have been built // mem xsection = 4 * roiBB.width() * SKIPSMImagePixelType // + 4 * roiBB.width() * SKIPSMAlphaPixelType // mem usage after = anInputUnion*ImageValueType + 2*anInputUnion*AlphaValueType // + (4/3)*roiBB*MaskPyramidType // + 2*(4/3)*roiBB*ImagePyramidType long long bytes = anInputUnion.area() * (sizeof(ImagePixelType) + 2 * sizeof(AlphaPixelType)) + (4/3) * roiBB.area() * (sizeof(MaskPyramidPixelType) + 2 * sizeof(ImagePyramidPixelType)) + (4 * roiBB.width()) * (sizeof(SKIPSMImagePixelType) + sizeof(SKIPSMAlphaPixelType)); std::cerr << command << ": info: estimated space required for this blend step: " << static_cast(ceil(bytes / 1000000.0)) << "MB" << std::endl; } // Create a version of roiBB relative to uBB upperleft corner. // This is to access roi within images of size uBB. // For example, the mask. vigra::Rect2D roiBB_uBB = roiBB; roiBB_uBB.moveBy(-uBB.upperLeft()); // Build Gaussian pyramid from mask. std::vector *maskGP = gaussianPyramid(numLevels, wraparoundForBlend, vigra_ext::apply(roiBB_uBB, srcImageRange(*mask))); #ifdef DEBUG_EXPORT_PYRAMID exportPyramid(maskGP, "mask"); #endif // mem usage before = MaskType*ubb + 2*anInputUnion*ImageValueType + 2*anInputUnion*AlphaValueType // mem usage xsection = 3 * roiBB.width * MaskPyramidType // mem usage after = MaskType*ubb + 2*anInputUnion*ImageValueType + 2*anInputUnion*AlphaValueType // + (4/3)*roiBB*MaskPyramidType // Now it is safe to make changes to mask image. // Black out the ROI in the mask. // Make an roiBounds relative to uBB origin. vigra::initImage(vigra_ext::apply(roiBB_uBB, destImageRange(*mask)), vigra::NumericTraits::zero()); // Copy pixels inside whiteBB and inside white part of mask into black image. // These are pixels where the white image contributes outside of the ROI. // We cannot modify black image inside the ROI yet because we haven't built the // black pyramid. vigra::copyImageIf(vigra_ext::apply(uBB, srcImageRange(*(whitePair.first))), maskImage(*mask), vigra_ext::apply(uBB, destImage(*(blackPair.first)))); // We no longer need the mask. delete mask; // mem usage after = 2*anInputUnion*ImageValueType + // 2*anInputUnion*AlphaValueType + // (4/3)*roiBB*MaskPyramidType // Build Laplacian pyramid from white image. std::vector* whiteLP = laplacianPyramid ("whiteGP", numLevels, wraparoundForBlend, vigra_ext::apply(roiBB, srcImageRange(*(whitePair.first))), vigra_ext::apply(roiBB, maskImage(*(whitePair.second)))); // mem usage after = 2*anInputUnion*ImageValueType + 2*anInputUnion*AlphaValueType // + (4/3)*roiBB*MaskPyramidType + (4/3)*roiBB*ImagePyramidType // mem xsection = 4 * roiBB.width() * SKIPSMImagePixelType // + 4 * roiBB.width() * SKIPSMAlphaPixelType // We no longer need the white rgb data. delete whitePair.first; // mem usage after = anInputUnion*ImageValueType + 2*anInputUnion*AlphaValueType // + (4/3)*roiBB*MaskPyramidType + (4/3)*roiBB*ImagePyramidType // Build Laplacian pyramid from black image. std::vector* blackLP = laplacianPyramid ("blackGP", numLevels, wraparoundForBlend, vigra_ext::apply(roiBB, srcImageRange(*(blackPair.first))), vigra_ext::apply(roiBB, maskImage(*(blackPair.second)))); #ifdef DEBUG_EXPORT_PYRAMID exportPyramid(blackLP, "enblend_black_lp"); #endif // Peak memory xsection is here! // mem xsection = 4 * roiBB.width() * SKIPSMImagePixelType // + 4 * roiBB.width() * SKIPSMAlphaPixelType // mem usage after = anInputUnion*ImageValueType + 2*anInputUnion*AlphaValueType // + (4/3)*roiBB*MaskPyramidType // + 2*(4/3)*roiBB*ImagePyramidType // Make the black image alpha equal to the union of the // white and black alpha channels. vigra::initImageIf(vigra_ext::apply(whiteBB, destImageRange(*(blackPair.second))), vigra_ext::apply(whiteBB, maskImage(*(whitePair.second))), vigra::NumericTraits::max()); // We no longer need the white alpha data. delete whitePair.second; // mem usage after = anInputUnion*ImageValueType + anInputUnion*AlphaValueType // + (4/3)*roiBB*MaskPyramidType + 2*(4/3)*roiBB*ImagePyramidType // Blend pyramids ConvertScalarToPyramidFunctor whiteMask; blend(maskGP, whiteLP, blackLP, whiteMask(vigra::NumericTraits::max())); // delete mask pyramid #ifdef DEBUG_EXPORT_PYRAMID exportPyramid(maskGP, "enblend_mask_gp"); #endif for (unsigned int i = 0; i < maskGP->size(); i++) { delete (*maskGP)[i]; } delete maskGP; // mem usage after = anInputUnion*ImageValueType + anInputUnion*AlphaValueType + 2*(4/3)*roiBB*ImagePyramidType // delete white pyramid #ifdef DEBUG_EXPORT_PYRAMID exportPyramid(whiteLP, "enblend_white_lp"); #endif for (unsigned int i = 0; i < whiteLP->size(); i++) { delete (*whiteLP)[i]; } delete whiteLP; // mem usage after = anInputUnion*ImageValueType + anInputUnion*AlphaValueType + (4/3)*roiBB*ImagePyramidType #ifdef DEBUG_EXPORT_PYRAMID exportPyramid(blackLP, "enblend_blend_lp"); #endif // collapse black pyramid collapsePyramid(wraparoundForBlend, blackLP); // copy collapsed black pyramid into black image ROI, using black alpha mask. copyFromPyramidImageIf (srcImageRange(*((*blackLP)[0])), vigra_ext::apply(roiBB, maskImage(*(blackPair.second))), vigra_ext::apply(roiBB, destImage(*(blackPair.first)))); // delete black pyramid for (unsigned int i = 0; i < blackLP->size(); i++) { delete (*blackLP)[i]; } delete blackLP; // mem usage after = anInputUnion*ImageValueType + anInputUnion*AlphaValueType // Checkpoint results. if (Checkpoint) { if (Verbose >= VERBOSE_CHECKPOINTING_MESSAGES) { std::cerr << command << ": info: "; if (imageInfoList.empty()) { std::cerr << "writing final output" << std::endl; } else { std::cerr << "checkpointing" << std::endl; } } checkpoint(blackPair, anOutputImageInfo); } // Now set blackBB to uBB. blackBB = uBB; ++m; ++inputFileNameIterator; } // end main blending loop if (!StopAfterMaskGeneration && !Checkpoint) { if (Verbose >= VERBOSE_CHECKPOINTING_MESSAGES) { std::cerr << command << ": info: writing final output" << std::endl; } checkpoint(blackPair, anOutputImageInfo); } delete blackPair.first; delete blackPair.second; } } // namespace enblend #endif /* __ENBLEND_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/win32helpers/0000755000175000017500000000000012676432767014412 500000000000000enblend-enfuse-4.2/src/win32helpers/CMakeLists.txt0000644000175000017500000000010312603013120017024 00000000000000if (WIN32) add_library(getopt STATIC getopt.c getopt.h) endif() enblend-enfuse-4.2/src/win32helpers/getopt.c0000644000175000017500000005274112070530376015770 00000000000000/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 Free Software Foundation, Inc. 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* NOTE!!! AIX requires this to be the first thing in the file. Do not put ANYTHING before it! */ #if !defined (__GNUC__) && defined (_AIX) #pragma alloca #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef __GNUC__ #define alloca __builtin_alloca #else /* not __GNUC__ */ #if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__)))) #include #else #ifndef _AIX char *alloca (); #endif #endif /* alloca.h */ #endif /* not __GNUC__ */ #if !__STDC__ && !defined(const) && IN_GCC #define const #endif /* This tells Alpha OSF/1 not to define a getopt prototype in . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #undef alloca /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #else /* Not GNU C library. */ #if defined(__IBMC__) || defined(__IBMCPP__) || defined(_MSC_VER) #include #ifdef _MSC_VER #include #undef __alloca #define __alloca _alloca #else #undef alloca #define alloca _alloca #endif #else #define __alloca alloca #endif /* IBMCSet */ #endif /* GNU C library. */ /* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a long-named option. Because this is not POSIX.2 compliant, it is being phased out. */ /* #define GETOPT_COMPAT */ /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = 0; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return EOF with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; #if defined(__GNU_LIBRARY__) || defined(__IBMC__) || defined(__IBMCPP__) || defined(_MSC_VER) /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #define my_bcopy(src, dst, n) memcpy ((dst), (src), (n)) #else /* Avoid depending on library functions or files whose names are inconsistent. */ char *getenv (); static char * #if __STDC__ || _MSC_VER my_index (const char *str, int chr) #else my_index (str, chr) const char *str; int chr; #endif { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } static void #if __STDC__ || _MSC_VER my_bcopy (const char *from, char *to, int size) #else my_bcopy (from, to, size) const char *from; char *to; int size; #endif { int i; for (i = 0; i < size; i++) to[i] = from[i]; } #endif /* GNU C library. */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ static void #if __STDC__ || _MSC_VER exchange (char **argv) #else exchange (argv) char **argv; #endif { int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *); char **temp = (char **) __alloca (nonopts_size); /* Interchange the two blocks of data in ARGV. */ my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size); my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt], (optind - last_nonopt) * sizeof (char *)); my_bcopy ((char *) temp, (char *) &argv[first_nonopt + optind - last_nonopt], nonopts_size); /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns `EOF'. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int #if __STDC__ || _MSC_VER _getopt_internal (int argc, char *const *argv, const char *optstring, const struct option *longopts, int *longind, int long_only) #else _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; #endif { int option_index; optarg = 0; /* Initialize the internal data when the first call is made. Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ if (optind == 0) { first_nonopt = last_nonopt = optind = 1; nextchar = NULL; /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (getenv ("POSIXLY_CORRECT") != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; } if (nextchar == NULL || *nextchar == '\0') { if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Now skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0') #ifdef GETOPT_COMPAT && (longopts == NULL || argv[optind][0] != '+' || argv[optind][1] == '\0') #endif /* GETOPT_COMPAT */ ) optind++; last_nonopt = optind; } /* Special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return EOF; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if ((argv[optind][0] != '-' || argv[optind][1] == '\0') #ifdef GETOPT_COMPAT && (longopts == NULL || argv[optind][0] != '+' || argv[optind][1] == '\0') #endif /* GETOPT_COMPAT */ ) { if (ordering == REQUIRE_ORDER) return EOF; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Start decoding its characters. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } if (longopts != NULL && ((argv[optind][0] == '-' && (argv[optind][1] == '-' || long_only)) #ifdef GETOPT_COMPAT || argv[optind][0] == '+' #endif /* GETOPT_COMPAT */ )) { const struct option *p; char *s = nextchar; int exact = 0; int ambig = 0; const struct option *pfound = NULL; int indfound = 0; while (*s && *s != '=') s++; /* Test all options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, s - nextchar)) { if ((size_t) (s - nextchar) == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*s) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = s + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, "%s: option `%c%s' doesn't allow an argument\n", argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, "%s: option `%s' requires an argument\n", argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' #ifdef GETOPT_COMPAT || argv[optind][0] == '+' #endif /* GETOPT_COMPAT */ || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar); else /* +option or -option */ fprintf (stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; return '?'; } } /* Look at and handle the next option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { #if 0 if (c < 040 || c >= 0177) fprintf (stderr, "%s: unrecognized option, character code 0%o\n", argv[0], c); else fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c); #else /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); #endif } optopt = c; return '?'; } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = 0; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { #if 0 fprintf (stderr, "%s: option `-%c' requires an argument\n", argv[0], c); #else /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: option requires an argument -- %c\n", argv[0], c); #endif } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int #if __STDC__ || _MSC_VER getopt (int argc, char *const *argv, const char *optstring) #else getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; #endif { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind) { return _getopt_internal(argc, argv, shortopts, longopts, longind, 0); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int #if __STDC__ || _MSC_VER main (int argc, char **argv) #else main (argc, argv) int argc; char **argv; #endif { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == EOF) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ enblend-enfuse-4.2/src/win32helpers/getopt.h0000644000175000017500000001067012070530376015770 00000000000000/* Declarations for getopt. Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if __STDC__ || _MSC_VER || defined(XP_OS2_VACPP) const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if __STDC__ || _MSC_VER || defined( XP_OS2_VACPP ) #if defined(__GNU_LIBRARY__) || defined( XP_OS2_VACPP ) || defined(_MSC_VER) /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ extern int getopt (); #endif /* not __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* not __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ enblend-enfuse-4.2/src/win32helpers/Makefile.am0000644000175000017500000000010212070530376016336 00000000000000EXTRA_DIST = \ getopt.h getopt.c \ CMakeLists.txt enblend-enfuse-4.2/src/win32helpers/Makefile.in0000644000175000017500000003141312676432431016365 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/win32helpers DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/_ac_latex_test.m4 \ $(top_srcdir)/m4/ac_latex_class.m4 \ $(top_srcdir)/m4/ac_latex_package.m4 \ $(top_srcdir)/m4/ac_prog_ar.m4 \ $(top_srcdir)/m4/ac_prog_latex.m4 \ $(top_srcdir)/m4/ac_type_sig_atomic_t.m4 \ $(top_srcdir)/m4/ax_boost_base.m4 \ $(top_srcdir)/m4/ax_cxx_as_const.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/ax_openmp.m4 \ $(top_srcdir)/m4/ax_prog_perl_modules.m4 \ $(top_srcdir)/m4/ax_with_prog.m4 $(top_srcdir)/m4/lrint.m4 \ $(top_srcdir)/m4/lrintf.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONVERT = @CONVERT@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_IMPLEMENTATION = @DL_IMPLEMENTATION@ DOT = @DOT@ DVIPDF = @DVIPDF@ DVIPS = @DVIPS@ DYNAMIC_TEX_PREAMBLE = @DYNAMIC_TEX_PREAMBLE@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_LIBS = @EXTRA_LIBS@ GNUPLOT = @GNUPLOT@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_INLINE = @HAVE_INLINE@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LATEX = @LATEX@ LATEX2HTML = @LATEX2HTML@ LATEX2HTML_LIBDIR = @LATEX2HTML_LIBDIR@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ M4 = @M4@ MAKEINDEX = @MAKEINDEX@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ OPENEXR_LIBS = @OPENEXR_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SPLITHTML = @SPLITHTML@ STRIP = @STRIP@ SVGCONVERT = @SVGCONVERT@ TEXLOGANALYSER = @TEXLOGANALYSER@ VERSION = @VERSION@ VIGRAIMPEX_LIB = @VIGRAIMPEX_LIB@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ amsmath = @amsmath@ bindir = @bindir@ bold_extra = @bold_extra@ boretti_classesansparametre = @boretti_classesansparametre@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ color = @color@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enumitem = @enumitem@ exec_prefix = @exec_prefix@ float = @float@ footnote = @footnote@ graphicx = @graphicx@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hyperref = @hyperref@ hyphenat = @hyphenat@ ifpdf = @ifpdf@ includedir = @includedir@ index = @index@ infodir = @infodir@ install_sh = @install_sh@ latex = @latex@ latexsym = @latexsym@ libdir = @libdir@ libexecdir = @libexecdir@ listings = @listings@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ microtype = @microtype@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ ragged2e = @ragged2e@ refrep = @refrep@ report = @report@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shorttoc = @shorttoc@ srcdir = @srcdir@ suffix = @suffix@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ url = @url@ xstring = @xstring@ EXTRA_DIST = \ getopt.h getopt.c \ CMakeLists.txt all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/win32helpers/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/win32helpers/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: enblend-enfuse-4.2/src/anneal.h0000644000175000017500000007576712662065361013425 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef ANNEAL_H_INCLUDED #define ANNEAL_H_INCLUDED #ifdef HAVE_CONFIG_H #include #endif #include #include #include #ifdef _WIN32 #include #else #include #endif #include #include #include "masktypedefs.h" #include "muopt.h" #include "opencl.h" #include "opencl_anneal.h" #include "openmp_lock.h" #include "timer.h" #ifdef OPENCL namespace GPU { extern std::unique_ptr StateProbabilities; } #endif // Nicol N. Schraudolph // "A Fast, Compact Approximation of the Exponential Function" // Neural Computation, vol. 11, pages 853--862, 1999. #define SCHRAUDOLPH_EXPONENT_A (1048576.0 / M_LN2) #define SCHRAUDOLPH_EXPONENT_A_INT 1512775 inline static double schraudolph_exp(double x) { if (EXPECT_RESULT(x > 709.0, false)) // log(std::numeric_limits::max()) = 709.783 { return std::numeric_limits::infinity(); } else if (EXPECT_RESULT(x < -708.0, false)) // log(std::numeric_limits::min()) = -708.396 { return double(); } else { union schraudolph { double floating_point_value; struct { #if __BYTE_ORDER == __LITTLE_ENDIAN unsigned least_significant_part; int most_significant_part; #else int most_significant_part; unsigned least_significant_part; #endif } integral_decomposition; } s; s.integral_decomposition.least_significant_part = 0U; s.integral_decomposition.most_significant_part = SCHRAUDOLPH_EXPONENT_A * x + (0x3ff00000 - 60801); return s.floating_point_value; } } namespace enblend { inline static vigra::Diff2D normal_vector(const vigra::Point2D& a_previous_point, const vigra::Point2D& a_current_point, const vigra::Point2D& a_next_point) { // vp: vector from a_previous_point to a_current_point const vigra::Diff2D vp(a_current_point.x - a_previous_point.x, a_current_point.y - a_previous_point.y); // vn: vector from a_current_point to a_next_point const vigra::Diff2D vn(a_next_point.x - a_current_point.x, a_next_point.y - a_current_point.y); // np: normal to vp const vigra::Diff2D np(-vp.y, vp.x); // nn: normal to vn const vigra::Diff2D nn(-vn.y, vn.x); // Answer normal vector at a_current_point; // normal points to the left of vp and vn. return np + nn; } template class GDAConfiguration { public: typedef typename CostImage::PixelType CostImagePixelType; typedef typename vigra::NumericTraits::Promote CostImagePromoteType; GDAConfiguration(const CostImage* const d, Segment* v, VisualizeImage* const vi) : costImage(d), visualizeStateSpaceImage(vi) { kMax = 1; distanceWeight = 1.0; mismatchWeight = 1.0; const int costImageShortDimension = std::min(costImage->width(), costImage->height()); // Determine state space of currentPoint const int stateSpaceWidth = costImageShortDimension / 3; vigra::Point2D previousPoint = v->back().second; for (Segment::iterator current = v->begin(); current != v->end();) { bool currentMoveable = current->first; vigra::Point2D currentPoint = current->second; ++current; vigra::Point2D nextPoint = current == v->end() ? v->begin()->second : current->second; mfEstimates.push_back(currentPoint); std::vector* stateSpace = new std::vector(); pointStateSpaces.push_back(stateSpace); std::vector* stateDistances = new std::vector(); pointStateDistances.push_back(stateDistances); vigra::Diff2D normal = normal_vector(previousPoint, currentPoint, nextPoint); const double normal_magnitude = normal.magnitude(); if (currentMoveable && normal_magnitude > std::numeric_limits::epsilon()) { normal *= stateSpaceWidth / normal_magnitude; vigra::Diff2D leftPoint = currentPoint + normal; vigra::Diff2D rightPoint = currentPoint - normal; // Choose a reasonable number of state points between these extremes const int lineLength = std::max(std::abs(rightPoint.x - leftPoint.x), std::abs(rightPoint.y - leftPoint.y)); const int spaceBetweenPoints = static_cast(ceil(lineLength / static_cast(AnnealPara.kmax))); vigra::LineIterator linePoint(currentPoint, leftPoint); for (int i = 0; i < (lineLength + 1) / 2; ++i, ++linePoint) { // Stop searching along the line if we leave the // cost image or enter a max-cost region. if (!costImage->isInside(*linePoint)) { break; } else if ((*costImage)[*linePoint] == vigra::NumericTraits::max()) { break; } else if (i % spaceBetweenPoints == 0) { stateSpace->push_back(vigra::Point2D(*linePoint)); stateDistances->push_back(std::max(std::abs(linePoint->x - currentPoint.x), std::abs(linePoint->y - currentPoint.y)) / 2); if (visualizeStateSpaceImage) { (*visualizeStateSpaceImage)[*linePoint] = VISUALIZE_STATE_SPACE; } } } linePoint = vigra::LineIterator(currentPoint, rightPoint); ++linePoint; for (int i = 1; i < 1 + lineLength / 2; ++i, ++linePoint) { // Stop searching along the line if we leave the // cost image or enter a max-cost region. if (!costImage->isInside(*linePoint)) { break; } else if ((*costImage)[*linePoint] == vigra::NumericTraits::max()) { break; } else if (i % spaceBetweenPoints == 0) { stateSpace->push_back(vigra::Point2D(*linePoint)); stateDistances->push_back(std::max(std::abs(linePoint->x - currentPoint.x), std::abs(linePoint->y - currentPoint.y)) / 2); if (visualizeStateSpaceImage) { (*visualizeStateSpaceImage)[*linePoint] = VISUALIZE_STATE_SPACE; } } } } if (stateSpace->size() == 0) { stateSpace->push_back(currentPoint); stateDistances->push_back(0); if (visualizeStateSpaceImage && costImage->isInside(currentPoint)) { (*visualizeStateSpaceImage)[currentPoint] = VISUALIZE_STATE_SPACE_INSIDE; } } const unsigned int localK = stateSpace->size(); if (localK > AnnealPara.kmax) { std::cerr << command << ": local k = " << localK << " > k_max = " << AnnealPara.kmax << std::endl; exit(1); } kMax = std::max(kMax, localK); pointStateProbabilities.push_back(new std::vector(localK, 1.0 / localK)); convergedPoints.push_back(localK < 2); previousPoint = currentPoint; } tau = AnnealPara.tau; deltaEMax = AnnealPara.deltaEMax; deltaEMin = AnnealPara.deltaEMin; const double kmax = static_cast(kMax); if (kmax > 2.5) { tInitial = ceil(deltaEMax / log(kmax / (kmax - 2.0))); tFinal = deltaEMin / log(kmax * kmax - kmax - 1.0); } else { tInitial = deltaEMax; tFinal = deltaEMin; } } virtual ~GDAConfiguration() { std::for_each(pointStateSpaces.begin(), pointStateSpaces.end(), [](std::vector* x) {delete x;}); std::for_each(pointStateProbabilities.begin(), pointStateProbabilities.end(), [](std::vector* x) {delete x;}); std::for_each(pointStateDistances.begin(), pointStateDistances.end(), [](std::vector* x) {delete x;}); } void run() { int progressIndicator = 1; int numIterations = static_cast(ceil(log(tFinal / tInitial) / log(tau))); int iterationCount = 0; int iterationsPerTick = (numIterations + 3) / 4; tCurrent = tInitial; while (kMax > 1 && tCurrent > tFinal) { const double epsilon = 1.0 / kMax; const unsigned int eta = static_cast(ceil(log(epsilon) / log(((kMax - 2.0) / (2.0 * kMax) * exp(-tCurrent / deltaEMax)) + 0.5))); if (Verbose >= VERBOSE_GDA_MESSAGES) { const std::ios_base::fmtflags ioFlags(std::cerr.flags()); std::cerr << "\n" << command << ": info: t = " << std::scientific << std::setprecision(3) << tCurrent << ", eta = " << std::setw(4) << eta << ", k_max = " << std::setw(3) << kMax; std::cerr.flush(); std::cerr.flags(ioFlags); } for (unsigned int i = 0; i < eta; i++) { iterate(); } tCurrent *= tau; if (Verbose >= VERBOSE_GDA_MESSAGES) { int numConvergedPoints = 0; for (unsigned int i = 0; i < convergedPoints.size(); i++) { if (convergedPoints[i]) { numConvergedPoints++; } } std::cerr << ", " << numConvergedPoints << " of " << convergedPoints.size() << " points converged"; std::cerr.flush(); } else if (Verbose >= VERBOSE_MASK_MESSAGES && iterationCount % iterationsPerTick == 0) { std::cerr << " " << progressIndicator << "/4"; progressIndicator++; std::cerr.flush(); } iterationCount++; } if (visualizeStateSpaceImage) { // Remaining unconverged state space points for (unsigned int i = 0; i < pointStateSpaces.size(); ++i) { std::vector* stateSpace = pointStateSpaces[i]; for (unsigned int j = 0; j < stateSpace->size(); ++j) { vigra::Point2D point = (*stateSpace)[j]; if (visualizeStateSpaceImage->isInside(point)) { (*visualizeStateSpaceImage)[point] = VISUALIZE_STATE_SPACE_UNCONVERGED; } } } } if (Verbose >= VERBOSE_GDA_MESSAGES) { std::cerr << std::endl; for (unsigned int i = 0; i < convergedPoints.size(); i++) { if (!convergedPoints[i]) { std::cerr << command << ": info: unconverged point: " << std::endl; std::vector* stateSpace = pointStateSpaces[i]; std::vector* stateProbabilities = pointStateProbabilities[i]; const unsigned int localK = stateSpace->size(); for (unsigned int state = 0; state < localK; ++state) { std::cerr << command << ": info: state " << (*stateSpace)[state] << ", weight = " << (*stateProbabilities)[state] << std::endl; } std::cerr << command << ": info: mfEstimate = " << mfEstimates[i] << std::endl; } } } } const std::vector& getCurrentPoints() const { return mfEstimates; } void setOptimizerWeights(double aDistanceWeight, double aMismatchWeight) { // IMPLEMENTATION NOTE: We normalize to 2.0, because we // want to reproduce the results of Enblend-3.2. Up to // Enblend-3.2 the distanceWeight and mismatchWeight were both // fixed at 1.0. const double sum = 0.5 * (aDistanceWeight + aMismatchWeight); assert(aDistanceWeight >= 0.0); assert(aMismatchWeight >= 0.0); assert(sum > 0.0); distanceWeight = aDistanceWeight / sum; mismatchWeight = aMismatchWeight / sum; } protected: virtual void calculateStateProbabilities() { const int mf_size = static_cast(mfEstimates.size()); #ifdef OPENMP #pragma omp parallel #endif { double* E = new double[kMax]; double* Pi = new double[kMax]; #ifdef OPENMP #pragma omp for nowait schedule(guided) #endif for (int index = 0; index < mf_size; ++index) { // Skip updating points that have already converged. convergedPointsLock.set(); if (convergedPoints[index]) { convergedPointsLock.unset(); continue; } convergedPointsLock.unset(); const std::vector* stateSpace = pointStateSpaces[index]; std::vector* stateProbabilities = pointStateProbabilities[index]; const std::vector* stateDistances = pointStateDistances[index]; const unsigned int localK = stateSpace->size(); const int lastIndex = index == 0 ? mf_size - 1 : index - 1; const unsigned int nextIndex = (index + 1) % mf_size; const vigra::Point2D lastPointEstimate = mfEstimates[lastIndex]; const bool lastPointInCostImage = costImage->isInside(lastPointEstimate); const vigra::Point2D nextPointEstimate = mfEstimates[nextIndex]; const bool nextPointInCostImage = costImage->isInside(nextPointEstimate); // Calculate E values. for (unsigned i = 0U; i < localK; ++i) { const vigra::Point2D currentPoint = (*stateSpace)[i]; const int distanceCost = (*stateDistances)[i]; int mismatchCost = 0; if (lastPointInCostImage) { mismatchCost += costImageCost(lastPointEstimate, currentPoint); } if (nextPointInCostImage) { mismatchCost += costImageCost(currentPoint, nextPointEstimate); } const double cost = distanceWeight * static_cast(distanceCost) + mismatchWeight * static_cast(mismatchCost); E[i] = cost / tCurrent; Pi[i] = 0.0; } timer::WallClock wall_clock; wall_clock.start(); // Calculate new stateProbabilities // An = 1 / (1 + exp((E[j] - E[i]) / tCurrent)) // pi[j]' = 1/K * sum_(0)_(k-1) An(i,j) * (pi[i] + pi[j]) for (unsigned j = 0U; j < localK; ++j) { const double piTj = (*stateProbabilities)[j]; Pi[j] += piTj; const double ej = E[j]; for (unsigned i = j + 1U; i < localK; ++i) { const double piT = (*stateProbabilities)[i] + piTj; double piTAn = piT / (1.0 + schraudolph_exp(ej - E[i])); if (EXPECT_RESULT(std::isnan(piTAn), false)) { // exp term is infinity or zero. piTAn = ej > E[i] ? 0.0 : piT; } Pi[j] += piTAn; Pi[i] += piT - piTAn; } (*stateProbabilities)[j] = Pi[j] / localK; } wall_clock.stop(); if (parameter::as_boolean("time-state-probabilities", false)) { ocl::StowFormatFlags _; std::cerr << "\n" << command << ": timing: wall-clock runtime of `Calculate New State Probabilities' (CPU): " << std::setprecision(3) << 1e6 * wall_clock.value() << " µs\n" << std::endl; } } delete [] E; delete [] Pi; } // omp parallel } void iterate() { calculateStateProbabilities(); kMax = 1; size_t kmax_local = 1; #ifdef OPENMP #pragma omp parallel firstprivate(kmax_local) #endif { #ifdef OPENMP #pragma omp for nowait schedule(guided) #endif for (int index = 0; index < static_cast(pointStateSpaces.size()); ++index) { convergedPointsLock.set(); if (convergedPoints[index]) { convergedPointsLock.unset(); continue; } convergedPointsLock.unset(); std::vector* stateSpace = pointStateSpaces[index]; std::vector* stateProbabilities = pointStateProbabilities[index]; std::vector* stateDistances = pointStateDistances[index]; unsigned int localK = stateSpace->size(); double estimateX = 0.0; double estimateY = 0.0; // Make new mean field estimates. double totalWeight = 0.0; bool hasHighWeightState = false; for (unsigned int k = 0; k < localK; ++k) { const double weight = (*stateProbabilities)[k]; totalWeight += weight; if (weight > 0.99) { hasHighWeightState = true; } const vigra::Point2D state = (*stateSpace)[k]; estimateX += weight * static_cast(state.x); estimateY += weight * static_cast(state.y); } estimateX /= totalWeight; estimateY /= totalWeight; vigra::Point2D newEstimate(vigra::NumericTraits::fromRealPromote(estimateX), vigra::NumericTraits::fromRealPromote(estimateY)); // Sanity check if (!costImage->isInside(newEstimate)) { cerrLock.set(); std::cerr << command << ": warning: new mean field estimate outside cost image" << std::endl; for (unsigned int state = 0; state < localK; ++state) { std::cerr << command << ": note: state " << (*stateSpace)[state] << " weight = " << (*stateProbabilities)[state] << std::endl; } std::cerr << command << ": note: new estimate = " << newEstimate << std::endl; cerrLock.unset(); // Skip this point from now on. convergedPointsLock.set(); convergedPoints[index] = true; convergedPointsLock.unset(); continue; } mfEstimates[index] = newEstimate; // Remove improbable solutions from the search space double totalWeights = 0.0; const double cutoffWeight = hasHighWeightState ? 0.50 : 0.00001; for (unsigned int k = 0; k < stateSpace->size(); ) { const double weight = (*stateProbabilities)[k]; if (weight < cutoffWeight) { // Replace this state with last state (*stateProbabilities)[k] = (*stateProbabilities)[stateProbabilities->size() - 1]; (*stateSpace)[k] = (*stateSpace)[stateSpace->size() - 1]; (*stateDistances)[k] = (*stateDistances)[stateDistances->size() - 1]; // Delete last state stateProbabilities->pop_back(); stateSpace->pop_back(); stateDistances->pop_back(); } else { totalWeights += weight; ++k; } } // Renormalize for (unsigned int k = 0; k < stateSpace->size(); ++k) { (*stateProbabilities)[k] /= totalWeights; } localK = stateSpace->size(); if (localK < 2) { convergedPointsLock.set(); convergedPoints[index] = true; convergedPointsLock.unset(); } kmax_local = std::max(kmax_local, stateProbabilities->size()); } kMaxLock.set(); kMax = std::max(kMax, static_cast(kmax_local)); kMaxLock.unset(); } // omp parallel } int costImageCost(const vigra::Point2D& start_point, const vigra::Point2D& end_point) const { typedef typename CostImage::ConstIterator CostIterator; const int shortLineThreshold = 8; // We penalize lines below this limit. const CostIterator end(costImage->upperLeft() + end_point); vigra::LineIterator lineEnd(end, end); vigra::LineIterator line(costImage->upperLeft() + start_point, end); int cost = 0; while (line != lineEnd) { cost += *line; ++line; } const int lineLength = std::max(std::abs(end_point.x - start_point.x), std::abs(end_point.y - start_point.y)); if (lineLength < shortLineThreshold) { cost += vigra::NumericTraits::max() * (shortLineThreshold - lineLength); } return cost; } bool segmentIntersect(const vigra::Point2D& l1a, const vigra::Point2D& l1b, const vigra::Point2D& l2a, const vigra::Point2D& l2b) const { int denom = (l2b.y - l2a.y) * (l1b.x - l1a.x) - (l2b.x - l2a.x) * (l1b.y - l1a.y); if (denom == 0) { return false; // lines are parallel or coincident } int uaNum = (l2b.x - l2a.x) * (l1a.y - l2a.y) - (l2b.y - l2a.y) * (l1a.x - l2a.x); int ubNum = (l1b.x - l1a.x) * (l1a.y - l2a.y) - (l1b.y - l1a.y) * (l1a.x - l2a.x); if (denom < 0) { uaNum *= -1; ubNum *= -1; denom *= -1; } if (uaNum > 0 && uaNum < denom && ubNum > 0 && ubNum < denom) { return true; } return false; } const CostImage *costImage; VisualizeImage *visualizeStateSpaceImage; // Mean-field estimates of current point locations std::vector mfEstimates; // State spaces of each point std::vector*> pointStateSpaces; // Probability vectors for each state space std::vector*> pointStateProbabilities; std::vector*> pointStateDistances; // Flags indicate which points have converged std::vector convergedPoints; omp::lock convergedPointsLock; // Initial Temperature double tInitial; // Final Temperature double tFinal; // Current Temperature double tCurrent; // Cooling constant double tau; // Maximum cost change possible by any single annealing move double deltaEMax; // Minimum cost change possible by any single annealing move double deltaEMin; // Largest state space over all points unsigned int kMax; omp::lock kMaxLock; // Weight factors for the distance of a point from the initial // seam line and the total mismatch accumulated along the seam // line segment. double distanceWeight;; double mismatchWeight; omp::lock cerrLock; }; // class GDAConfiguration #ifdef OPENCL template class GDAConfigurationGPU : public GDAConfiguration { typedef GDAConfiguration super; public: GDAConfigurationGPU(const CostImage* const d, Segment* v, VisualizeImage* const vi) : super(d, v, vi) { #ifdef DEBUG std::cerr << command << ": info: choose OpenCL accelaration for Anneal Snake" << std::endl; #endif } protected: void calculateStateProbabilities() override // GPU version { const int mf_size = static_cast(super::mfEstimates.size()); const size_t maximum_probability_vector_size = (*std::max_element(super::pointStateProbabilities.begin(), super::pointStateProbabilities.end(), [] (const std::vector* x, const std::vector* y) {return x->size() < y->size();}))->size(); // Method GPU::StateProbabilities->setup() allocates space for // `E' and `Pi' for us. In particular it will use the GPU's // favorite global memory. float* E; float* Pi; GPU::StateProbabilities->setup(maximum_probability_vector_size, static_cast(super::kMax), E, Pi); for (int index = 0; index < mf_size; ++index) { if (super::convergedPoints[index]) { continue; } const std::vector* stateSpace = super::pointStateSpaces[index]; std::vector* stateProbabilities = super::pointStateProbabilities[index]; const std::vector* stateDistances = super::pointStateDistances[index]; const int localK = static_cast(stateSpace->size()); const int lastIndex = (index == 0 ? mf_size : index) - 1; const int nextIndex = (index + 1) % mf_size; const vigra::Point2D lastPointEstimate = super::mfEstimates[lastIndex]; const bool lastPointInCostImage = super::costImage->isInside(lastPointEstimate); const vigra::Point2D nextPointEstimate = super::mfEstimates[nextIndex]; const bool nextPointInCostImage = super::costImage->isInside(nextPointEstimate); // Calculate E values. for (int i = 0; i < localK; ++i) { const vigra::Point2D currentPoint = (*stateSpace)[i]; const int distanceCost = (*stateDistances)[i]; int mismatchCost = 0; if (lastPointInCostImage) { mismatchCost += super::costImageCost(lastPointEstimate, currentPoint); } if (nextPointInCostImage) { mismatchCost += super::costImageCost(currentPoint, nextPointEstimate); } const double cost = super::distanceWeight * static_cast(distanceCost) + super::mismatchWeight * static_cast(mismatchCost); E[i] = static_cast(cost / super::tCurrent); Pi[i] = 0.0f; } // for i timer::WallClock wall_clock; wall_clock.start(); GPU::StateProbabilities->run(localK, stateProbabilities, super::kMax, E, Pi); wall_clock.stop(); if (parameter::as_boolean("time-state-probabilities", false)) { ocl::StowFormatFlags _; std::cerr << "\n" << command << ": timing: wall-clock runtime of `Calculate New State Probabilities' (GPU): " << std::setprecision(3) << 1e6 * wall_clock.value() << " µs\n" << std::endl; } } // for index GPU::StateProbabilities->teardown(); } }; // class GDAConfigurationGPU #endif // OPENCL template void annealSnake(const CostImage* const ci, const std::pair& optimizerWeights, Segment* snake, VisualizeImage* const vi) { timer::WallClock wall_clock; wall_clock.start(); #ifdef OPENCL const bool enable_kernel = parameter::as_boolean("gpu-kernel-anneal", true); std::unique_ptr > cfg((GPUContext && enable_kernel) ? new GDAConfigurationGPU(ci, snake, vi) : new GDAConfiguration(ci, snake, vi)); if (GPUContext && enable_kernel) { GPU::StateProbabilities->wait(); // Ensure that kernel was built. } #else std::unique_ptr > cfg(new GDAConfiguration(ci, snake, vi)); #endif cfg->setOptimizerWeights(optimizerWeights.first, optimizerWeights.second); cfg->run(); std::vector::const_iterator annealedPoint = cfg->getCurrentPoints().begin(); for (Segment::iterator snakePoint = snake->begin(); snakePoint != snake->end(); ++snakePoint, ++annealedPoint) { snakePoint->second = *annealedPoint; } wall_clock.stop(); if (parameter::as_boolean("time-anneal-snake", false)) { ocl::StowFormatFlags _; std::cerr << "\n" << command << ": timing: wall-clock runtime of `Anneal Snake': " << std::setprecision(3) << 1000.0 * wall_clock.value() << " ms\n" << std::endl; } } } // namespace enblend #endif // ANNEAL_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/mga.h0000644000175000017500000002205312641706002012676 00000000000000/* * Copyright (C) 2008-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __MGA_H__ #define __MGA_H__ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "common.h" namespace enblend { template class MultiGrayscaleAccessor { public: typedef ResultType value_type; MultiGrayscaleAccessor(const std::string& accessorName) { typedef typename vigra::NumericTraits::isScalar srcIsScalar; initializeTypeSpecific(srcIsScalar()); initialize(accessorName); } ResultType operator()(const InputType& x) const { typedef typename vigra::NumericTraits::isScalar srcIsScalar; return f(x, srcIsScalar()); } template ResultType operator()(const Iterator& i) const { typedef typename vigra::NumericTraits::isScalar srcIsScalar; return f(i, srcIsScalar()); } template ResultType operator()(const Iterator& i, Difference d) const { typedef typename vigra::NumericTraits::isScalar srcIsScalar; return f(i, d, srcIsScalar()); } static const std::string defaultGrayscaleAccessorName() { return "average"; //< default-grayscale-accessor average } private: typedef enum AccessorKind { AVERAGE, LSTAR, PRIMED_LSTAR, LIGHTNESS, VALUE, ANTI_VALUE, LUMINANCE, MIXER } AccKindType; typedef std::map NameMapType; typedef typename NameMapType::const_iterator NameMapConstIterType; #define CHANNEL_MIXER "channel-mixer" void initializeAccessorNameMap() { nameMap["average"] = AVERAGE; nameMap["l-star"] = LSTAR; nameMap["pl-star"] = PRIMED_LSTAR; nameMap["lightness"] = LIGHTNESS; nameMap["value"] = VALUE; nameMap["anti-value"] = ANTI_VALUE; nameMap["luminance"] = LUMINANCE; nameMap[CHANNEL_MIXER] = MIXER; } void initialize(const std::string& accessorName) { initializeAccessorNameMap(); if (accessorName.empty()) { kind = nameMap[defaultGrayscaleAccessorName()]; } else { std::string name(accessorName); std::transform(name.begin(), name.end(), name.begin(), tolower); NameMapConstIterType const k = nameMap.find(name); if (k == nameMap.end()) { char dummy; double red, green, blue; if (sscanf(name.c_str(), CHANNEL_MIXER "%[" NUMERIC_OPTION_DELIMITERS "]%lf%[" NUMERIC_OPTION_DELIMITERS "]%lf%[" NUMERIC_OPTION_DELIMITERS "]%lf", &dummy, &red, &dummy, &green, &dummy, &blue) == 6) { check_weights(red, green, blue); const double sum = red + green + blue; redWeight = red / sum; greenWeight = green / sum; blueWeight = blue / sum; kind = MIXER; } else { std::cerr << command << ": unknown grayscale projector \"" << accessorName << "\"" << std::endl; exit(1); } } else { kind = k->second; if (kind == MIXER) { std::cerr << command << ": \"" CHANNEL_MIXER "\" is a grayscale projector requiring\n" << command << ": arguments like e.g. \"channel-mixer:0.30:0.59:0.11\"" << std::endl; exit(1); } } } } void check_weights(double red, double green, double blue) const { // TODO: check for isnormal(WEIGHT) before comparison if (red < 0.0) { std::cerr << command << ": nonsensical weight of red channel (" << red << ")" << std::endl; exit(1); } if (green < 0.0) { std::cerr << command << ": nonsensical weight of green channel (" << green << ")" << std::endl; exit(1); } if (blue < 0.0) { std::cerr << command << ": nonsensical weight of blue channel (" << blue << ")" << std::endl; exit(1); } if (red + green + blue == 0.0) { std::cerr << command << ": sum of channel weights is zero" << std::endl; exit(1); } } void initializeTypeSpecific(vigra::VigraTrueType) {} void initializeTypeSpecific(vigra::VigraFalseType) { typedef typename InputType::value_type ValueType; rgb_to_lab_fun = vigra::RGB2LabFunctor(vigra::NumericTraits::max()); rgb_prime_to_lab_fun = vigra::RGBPrime2LabFunctor(vigra::NumericTraits::max()); } ResultType project(const InputType& x) const { typedef typename InputType::value_type ValueType; switch (kind) { case AVERAGE: return vigra::NumericTraits::fromRealPromote ((vigra::NumericTraits::toRealPromote(x.red()) + vigra::NumericTraits::toRealPromote(x.green()) + vigra::NumericTraits::toRealPromote(x.blue())) / 3.0); case LSTAR: { typedef typename vigra::RGB2LabFunctor::result_type LABResultType; const LABResultType y = rgb_to_lab_fun.operator()(x) / 100.0; return vigra::NumericTraits::fromRealPromote(vigra::NumericTraits::max() * y[0]); } case PRIMED_LSTAR: { typedef typename vigra::RGBPrime2LabFunctor::result_type LABResultType; const LABResultType y = rgb_prime_to_lab_fun.operator()(x) / 100.0; return vigra::NumericTraits::fromRealPromote(vigra::NumericTraits::max() * y[0]); } case LIGHTNESS: return vigra::NumericTraits::fromRealPromote ((std::min(x.red(), std::min(x.green(), x.blue())) + std::max(x.red(), std::max(x.green(), x.blue()))) / 2.0); case VALUE: return std::max(x.red(), std::max(x.green(), x.blue())); case ANTI_VALUE: return std::min(x.red(), std::min(x.green(), x.blue())); case LUMINANCE: return vigra::NumericTraits::fromRealPromote(x.luminance()); case MIXER: return vigra::NumericTraits::fromRealPromote (redWeight * vigra::NumericTraits::toRealPromote(x.red()) + greenWeight * vigra::NumericTraits::toRealPromote(x.green()) + blueWeight * vigra::NumericTraits::toRealPromote(x.blue())); } // never reached return ResultType(); } // RGB ResultType f(const InputType& x, vigra::VigraFalseType) const { return project(x); } template ResultType f(const Iterator& i, vigra::VigraFalseType) const { return project(*i); } template ResultType f(const Iterator& i, Difference d, vigra::VigraFalseType) const { return project(i[d]); } // grayscale ResultType f(const InputType& x, vigra::VigraTrueType) const {return x;} template ResultType f(const Iterator& i, vigra::VigraTrueType) const {return *i;} template ResultType f(const Iterator& i, Difference d, vigra::VigraTrueType) const {return i[d];} NameMapType nameMap; AccKindType kind; double redWeight, greenWeight, blueWeight; vigra::RGB2LabFunctor rgb_to_lab_fun; vigra::RGBPrime2LabFunctor rgb_prime_to_lab_fun; }; } // namespace enblend #endif /* __MGA_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/calculate_state_probabilities.cl0000644000175000017500000000750512641706002020353 00000000000000// Copyright (C) 2015, 2016 Christoph L. Spiel // // This file is part of Enblend. // // Enblend 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. // // Enblend 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 Enblend; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA inline static void new_state_probabilities(const int k, local float *sp, constant float *e, local float *pi, const int total_scratch_size, local float *scratch) { const int gid = get_global_id(0); // We use `scratch' for two arrays: `reciprocal_exp_delta_e' and // `reduce_scratch'. Each gets half of the available space. const int scratch_size = total_scratch_size / 2; local float *reciprocal_exp_delta_e = scratch; local float *reduce_scratch = scratch + scratch_size; for (int j = 0; j < k; j++) { const float x = native_divide(1.0f, 1.0f + native_exp(e[j] - e[gid])); #ifdef __FAST_RELAXED_MATH__ reciprocal_exp_delta_e[gid] = x; #else reciprocal_exp_delta_e[gid] = isnan(x) ? (e[j] > e[gid] ? 0.0f : 1.0f) : x; #endif barrier(CLK_LOCAL_MEM_FENCE); const float sp_j = sp[j] + sp[gid]; reduce_scratch[gid] = (gid <= j || gid >= k) ? 0.0f : sp_j * reciprocal_exp_delta_e[gid]; pi[gid] += (gid <= j || gid >= k) ? 0.0f : sp_j - reduce_scratch[gid]; barrier(CLK_LOCAL_MEM_FENCE); for (int s = scratch_size / 2; s > 0; s >>= 1) { if (gid < s) { reduce_scratch[gid] += reduce_scratch[gid + s]; } barrier(CLK_LOCAL_MEM_FENCE); } if (gid == 0) { const float pi_j = sp[j] + pi[j] + reduce_scratch[0]; pi[j] = pi_j; sp[j] = pi_j / (float) k; } } } #ifdef HAVE_EXTENSION_CL_KHR_FP64 #pragma OPENCL EXTENSION cl_khr_fp64: enable kernel void calculate_state_probabilities(const int k, global double *restrict global_sp, local float *sp, constant float *e, global float *restrict global_pi, local float *pi, const int total_scratch_size, local float *scratch) { const int gid = get_global_id(0); if (gid < k) { sp[gid] = (float) global_sp[gid]; pi[gid] = global_pi[gid]; } barrier(CLK_LOCAL_MEM_FENCE); new_state_probabilities(k, sp, e, pi, total_scratch_size, scratch); barrier(CLK_LOCAL_MEM_FENCE); if (gid < k) { global_sp[gid] = (double) sp[gid]; global_pi[gid] = pi[gid]; } } #else kernel void calculate_state_probabilities(const int k, global float *restrict global_sp, local float *sp, constant float *e, global float *restrict global_pi, local float *pi, const int total_scratch_size, local float *scratch) { const int gid = get_global_id(0); if (gid < k) { sp[gid] = global_sp[gid]; pi[gid] = global_pi[gid]; } barrier(CLK_LOCAL_MEM_FENCE); new_state_probabilities(k, sp, e, pi, total_scratch_size, scratch); barrier(CLK_LOCAL_MEM_FENCE); if (gid < k) { global_sp[gid] = sp[gid]; global_pi[gid] = pi[gid]; } } #endif // HAVE_EXTENSION_CL_KHR_FP64 enblend-enfuse-4.2/src/dynamic_loader/0000755000175000017500000000000012676432767015037 500000000000000enblend-enfuse-4.2/src/dynamic_loader/null_implementation.h0000644000175000017500000000331312641706002021161 00000000000000/* * Copyright (C) 2013-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef NULL_IMPLEMENTATION_H_INCLUDED #define NULL_IMPLEMENTATION_H_INCLUDED #ifdef HAVE_CONFIG_H #include #endif #include "dynamic_loader_implementation.h" class NullDynamicLoaderImplementation : public DynamicLoaderImplementation { typedef DynamicLoaderImplementation super; public: explicit NullDynamicLoaderImplementation(const std::string& a_library_name) : super(a_library_name) {} void open() {} void close() {} void* resolve(const std::string&) const {return nullptr;} }; // class NullDynamicLoaderImplementation class ActualDynamicLoaderImplementation : public NullDynamicLoaderImplementation { public: explicit ActualDynamicLoaderImplementation(const std::string& a_library_name) : NullDynamicLoaderImplementation(a_library_name) {} }; // class ActualDynamicLoaderImplementation #endif // NULL_IMPLEMENTATION_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/dynamic_loader/dynamic_loader.h0000644000175000017500000000502512641706002020056 00000000000000/* * Copyright (C) 2013-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef DYNAMIC_LOADER_H_INCLUDED #define DYNAMIC_LOADER_H_INCLUDED #ifdef HAVE_CONFIG_H #include #endif #include #include #if defined(GMODULE_DL) || defined(POSIX_DL) || defined(WIN32_DL) #define HAVE_DYNAMICLOADER_IMPL #endif class ActualDynamicLoaderImplementation; class DynamicLoader { public: DynamicLoader() = delete; explicit DynamicLoader(const std::string& a_library_name); DynamicLoader(const DynamicLoader& another_dynamic_loader); DynamicLoader& operator=(const DynamicLoader& another_dynamic_loader); ~DynamicLoader(); // Access symbols that do not require a teardown function to be // called on un-linking. void* resolve0(const std::string& a_symbol_name) const; template t resolve(const std::string& a_symbol_name) const { return static_cast(resolve0(a_symbol_name)); } // Interface of clean-up objects. class Teardown { public: Teardown() = delete; virtual void teardown(DynamicLoader*) = 0; virtual ~Teardown() {} }; // Gain access to a symbol and simultaneously register a clean-up // object, which can e.g. run a clean-up function for the symbol. void* resolve0(const std::string& a_symbol_name, Teardown* a_teardown_object); template t resolve(const std::string& a_symbol_name, Teardown* a_teardown_object) { return static_cast(resolve0(a_symbol_name, a_teardown_object)); } private: void finalize(); typedef std::vector observer_list; ActualDynamicLoaderImplementation* implementation_; observer_list observers_; }; // class DynamicLoader #endif // DYNAMIC_LOADER_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/dynamic_loader/dynamic_loader.cc0000644000175000017500000000526212641706002020217 00000000000000/* * Copyright (C) 2013-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H #include #endif #if defined(GMODULE_DL) #include "gmodule_implementation.h" // g_module_open(3) #elif defined(POSIX_DL) #include "posix_implementation.h" // dlopen(3) #elif defined(WIN32_DL) #include "win32_implementation.h" #else // This is the fallback class if no implementation class has been selected. #include "null_implementation.h" #endif #include "dynamic_loader.h" DynamicLoader::DynamicLoader(const std::string& a_library_name) : implementation_(new ActualDynamicLoaderImplementation(a_library_name)) { implementation_->open(); } DynamicLoader::DynamicLoader(const DynamicLoader& another_dynamic_loader) : implementation_(new ActualDynamicLoaderImplementation(another_dynamic_loader.implementation_->library_name())) { implementation_->open(); // Observer list of the new, copied instance is empty. } DynamicLoader& DynamicLoader::operator=(const DynamicLoader& another_dynamic_loader) { if (this != &another_dynamic_loader) { finalize(); observers_ = another_dynamic_loader.observers_; implementation_ = another_dynamic_loader.implementation_; } return *this; } DynamicLoader::~DynamicLoader() { finalize(); } // Access symbols that do not require a teardown function to be // called on un-linking. void* DynamicLoader::resolve0(const std::string& a_symbol_name) const { return implementation_->resolve(a_symbol_name); } // Gain access to a symbol and simultaneously register a clean-up // object, which can e.g. run a clean-up function for the symbol. void* DynamicLoader::resolve0(const std::string& a_symbol_name, Teardown* a_teardown_object) { observers_.push_back(a_teardown_object); return resolve0(a_symbol_name); } void DynamicLoader::finalize() { for (auto x : observers_) { x->teardown(this); } implementation_->close(); delete implementation_; } enblend-enfuse-4.2/src/dynamic_loader/win32_implementation.cc0000644000175000017500000000506612672731617021334 00000000000000/* * Copyright (C) 2015, 2016 Thomas Modes * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "global.h" // for enblend::trim #include "win32_implementation.h" WinDynamicLoaderImplementation::WinDynamicLoaderImplementation(const std::string& a_library_name) : super(a_library_name), handle_(nullptr) {} void WinDynamicLoaderImplementation::open() { if (handle_) { throw super::error("already open"); } handle_ = LoadLibrary(library_name().c_str()); if (!handle_) { throw super::error(GetLastErrorString()); } } void WinDynamicLoaderImplementation::close() { if (!handle_) { throw super::error("not open"); } if (!FreeLibrary(handle_)) { throw super::error(GetLastErrorString()); } } void* WinDynamicLoaderImplementation::resolve(const std::string& symbol_name) const { if (!handle_) { throw super::error("not open"); } void* symbol = (void*)GetProcAddress(handle_, symbol_name.c_str()); if (symbol == nullptr) { throw super::error(GetLastErrorString()); } return symbol; } const std::string WinDynamicLoaderImplementation::GetLastErrorString() { LPTSTR lpMsgBuf; DWORD lastError = GetLastError(); std::string errorMsg; if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, nullptr) > 0) { errorMsg = lpMsgBuf; // remove leading and trailing white spaces enblend::trim(errorMsg); LocalFree(lpMsgBuf); } else { errorMsg = "Unknown error"; } // add numeric error code errorMsg.append(" (Code: "); errorMsg.append(std::to_string(lastError)); errorMsg.append(")"); return errorMsg; } enblend-enfuse-4.2/src/dynamic_loader/posix_implementation.h0000644000175000017500000000332312641706002021352 00000000000000/* * Copyright (C) 2013-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef POSIX_IMPLEMENTATION_H_INCLUDED #define POSIX_IMPLEMENTATION_H_INCLUDED #ifdef HAVE_CONFIG_H #include #endif #include #include "dynamic_loader_implementation.h" class PosixDynamicLoaderImplementation : public DynamicLoaderImplementation { typedef DynamicLoaderImplementation super; public: explicit PosixDynamicLoaderImplementation(const std::string& a_library_name); void open(); void close(); void* resolve(const std::string& symbol_name) const; private: void* handle_; }; // class PosixDynamicLoaderImplementation class ActualDynamicLoaderImplementation : public PosixDynamicLoaderImplementation { public: explicit ActualDynamicLoaderImplementation(const std::string& a_library_name) : PosixDynamicLoaderImplementation(a_library_name) {} }; // class ActualDynamicLoaderImplementation #endif // POSIX_IMPLEMENTATION_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/dynamic_loader/Makefile.am0000644000175000017500000000153412603243004016764 00000000000000AM_CPPFLAGS = $(EXTRACPPFLAGS) AM_CFLAGS = $(EXTRACFLAGS) AM_CXXFLAGS = $(EXTRACXXFLAGS) AM_LDFLAGS = $(EXTRALDFLAGS) noinst_LIBRARIES = libdynamic_loader.a libdynamic_loader_a_SOURCES = \ dynamic_loader.h dynamic_loader.cc \ dynamic_loader_implementation.h dynamic_loader_implementation.cc \ null_implementation.h EXTRA_libdynamic_loader_a_SOURCES = \ gmodule_implementation.h gmodule_implementation.cc \ posix_implementation.h posix_implementation.cc \ win32_implementation.h win32_implementation.cc EXTRA_libdynamic_loader_a_DEPENDENCIES = $(DL_IMPLEMENTATION) libdynamic_loader_a_LIBADD = $(DL_IMPLEMENTATION) libdynamic_loader_a_CXXFLAGS = \ $(AM_CXXFLAGS) \ -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \ -I$(top_srcdir)/include -I$(top_srcdir)/src -I$(top_srcdir)/src/dynamic_loader enblend-enfuse-4.2/src/dynamic_loader/Makefile.in0000644000175000017500000007704112676432431017021 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/dynamic_loader DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/_ac_latex_test.m4 \ $(top_srcdir)/m4/ac_latex_class.m4 \ $(top_srcdir)/m4/ac_latex_package.m4 \ $(top_srcdir)/m4/ac_prog_ar.m4 \ $(top_srcdir)/m4/ac_prog_latex.m4 \ $(top_srcdir)/m4/ac_type_sig_atomic_t.m4 \ $(top_srcdir)/m4/ax_boost_base.m4 \ $(top_srcdir)/m4/ax_cxx_as_const.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/ax_openmp.m4 \ $(top_srcdir)/m4/ax_prog_perl_modules.m4 \ $(top_srcdir)/m4/ax_with_prog.m4 $(top_srcdir)/m4/lrint.m4 \ $(top_srcdir)/m4/lrintf.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libdynamic_loader_a_AR = $(AR) $(ARFLAGS) am__DEPENDENCIES_1 = libdynamic_loader_a_DEPENDENCIES = $(am__DEPENDENCIES_1) am_libdynamic_loader_a_OBJECTS = \ libdynamic_loader_a-dynamic_loader.$(OBJEXT) \ libdynamic_loader_a-dynamic_loader_implementation.$(OBJEXT) libdynamic_loader_a_OBJECTS = $(am_libdynamic_loader_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libdynamic_loader_a_SOURCES) \ $(EXTRA_libdynamic_loader_a_SOURCES) DIST_SOURCES = $(libdynamic_loader_a_SOURCES) \ $(EXTRA_libdynamic_loader_a_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONVERT = @CONVERT@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_IMPLEMENTATION = @DL_IMPLEMENTATION@ DOT = @DOT@ DVIPDF = @DVIPDF@ DVIPS = @DVIPS@ DYNAMIC_TEX_PREAMBLE = @DYNAMIC_TEX_PREAMBLE@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_LIBS = @EXTRA_LIBS@ GNUPLOT = @GNUPLOT@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_INLINE = @HAVE_INLINE@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LATEX = @LATEX@ LATEX2HTML = @LATEX2HTML@ LATEX2HTML_LIBDIR = @LATEX2HTML_LIBDIR@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ M4 = @M4@ MAKEINDEX = @MAKEINDEX@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ OPENEXR_LIBS = @OPENEXR_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SPLITHTML = @SPLITHTML@ STRIP = @STRIP@ SVGCONVERT = @SVGCONVERT@ TEXLOGANALYSER = @TEXLOGANALYSER@ VERSION = @VERSION@ VIGRAIMPEX_LIB = @VIGRAIMPEX_LIB@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ amsmath = @amsmath@ bindir = @bindir@ bold_extra = @bold_extra@ boretti_classesansparametre = @boretti_classesansparametre@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ color = @color@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enumitem = @enumitem@ exec_prefix = @exec_prefix@ float = @float@ footnote = @footnote@ graphicx = @graphicx@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hyperref = @hyperref@ hyphenat = @hyphenat@ ifpdf = @ifpdf@ includedir = @includedir@ index = @index@ infodir = @infodir@ install_sh = @install_sh@ latex = @latex@ latexsym = @latexsym@ libdir = @libdir@ libexecdir = @libexecdir@ listings = @listings@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ microtype = @microtype@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ ragged2e = @ragged2e@ refrep = @refrep@ report = @report@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shorttoc = @shorttoc@ srcdir = @srcdir@ suffix = @suffix@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ url = @url@ xstring = @xstring@ AM_CPPFLAGS = $(EXTRACPPFLAGS) AM_CFLAGS = $(EXTRACFLAGS) AM_CXXFLAGS = $(EXTRACXXFLAGS) AM_LDFLAGS = $(EXTRALDFLAGS) noinst_LIBRARIES = libdynamic_loader.a libdynamic_loader_a_SOURCES = \ dynamic_loader.h dynamic_loader.cc \ dynamic_loader_implementation.h dynamic_loader_implementation.cc \ null_implementation.h EXTRA_libdynamic_loader_a_SOURCES = \ gmodule_implementation.h gmodule_implementation.cc \ posix_implementation.h posix_implementation.cc \ win32_implementation.h win32_implementation.cc EXTRA_libdynamic_loader_a_DEPENDENCIES = $(DL_IMPLEMENTATION) libdynamic_loader_a_LIBADD = $(DL_IMPLEMENTATION) libdynamic_loader_a_CXXFLAGS = \ $(AM_CXXFLAGS) \ -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \ -I$(top_srcdir)/include -I$(top_srcdir)/src -I$(top_srcdir)/src/dynamic_loader all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/dynamic_loader/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/dynamic_loader/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libdynamic_loader.a: $(libdynamic_loader_a_OBJECTS) $(libdynamic_loader_a_DEPENDENCIES) $(EXTRA_libdynamic_loader_a_DEPENDENCIES) $(AM_V_at)-rm -f libdynamic_loader.a $(AM_V_AR)$(libdynamic_loader_a_AR) libdynamic_loader.a $(libdynamic_loader_a_OBJECTS) $(libdynamic_loader_a_LIBADD) $(AM_V_at)$(RANLIB) libdynamic_loader.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdynamic_loader_a-dynamic_loader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdynamic_loader_a-dynamic_loader_implementation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdynamic_loader_a-gmodule_implementation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdynamic_loader_a-posix_implementation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdynamic_loader_a-win32_implementation.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` libdynamic_loader_a-dynamic_loader.o: dynamic_loader.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -MT libdynamic_loader_a-dynamic_loader.o -MD -MP -MF $(DEPDIR)/libdynamic_loader_a-dynamic_loader.Tpo -c -o libdynamic_loader_a-dynamic_loader.o `test -f 'dynamic_loader.cc' || echo '$(srcdir)/'`dynamic_loader.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdynamic_loader_a-dynamic_loader.Tpo $(DEPDIR)/libdynamic_loader_a-dynamic_loader.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dynamic_loader.cc' object='libdynamic_loader_a-dynamic_loader.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -c -o libdynamic_loader_a-dynamic_loader.o `test -f 'dynamic_loader.cc' || echo '$(srcdir)/'`dynamic_loader.cc libdynamic_loader_a-dynamic_loader.obj: dynamic_loader.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -MT libdynamic_loader_a-dynamic_loader.obj -MD -MP -MF $(DEPDIR)/libdynamic_loader_a-dynamic_loader.Tpo -c -o libdynamic_loader_a-dynamic_loader.obj `if test -f 'dynamic_loader.cc'; then $(CYGPATH_W) 'dynamic_loader.cc'; else $(CYGPATH_W) '$(srcdir)/dynamic_loader.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdynamic_loader_a-dynamic_loader.Tpo $(DEPDIR)/libdynamic_loader_a-dynamic_loader.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dynamic_loader.cc' object='libdynamic_loader_a-dynamic_loader.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -c -o libdynamic_loader_a-dynamic_loader.obj `if test -f 'dynamic_loader.cc'; then $(CYGPATH_W) 'dynamic_loader.cc'; else $(CYGPATH_W) '$(srcdir)/dynamic_loader.cc'; fi` libdynamic_loader_a-dynamic_loader_implementation.o: dynamic_loader_implementation.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -MT libdynamic_loader_a-dynamic_loader_implementation.o -MD -MP -MF $(DEPDIR)/libdynamic_loader_a-dynamic_loader_implementation.Tpo -c -o libdynamic_loader_a-dynamic_loader_implementation.o `test -f 'dynamic_loader_implementation.cc' || echo '$(srcdir)/'`dynamic_loader_implementation.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdynamic_loader_a-dynamic_loader_implementation.Tpo $(DEPDIR)/libdynamic_loader_a-dynamic_loader_implementation.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dynamic_loader_implementation.cc' object='libdynamic_loader_a-dynamic_loader_implementation.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -c -o libdynamic_loader_a-dynamic_loader_implementation.o `test -f 'dynamic_loader_implementation.cc' || echo '$(srcdir)/'`dynamic_loader_implementation.cc libdynamic_loader_a-dynamic_loader_implementation.obj: dynamic_loader_implementation.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -MT libdynamic_loader_a-dynamic_loader_implementation.obj -MD -MP -MF $(DEPDIR)/libdynamic_loader_a-dynamic_loader_implementation.Tpo -c -o libdynamic_loader_a-dynamic_loader_implementation.obj `if test -f 'dynamic_loader_implementation.cc'; then $(CYGPATH_W) 'dynamic_loader_implementation.cc'; else $(CYGPATH_W) '$(srcdir)/dynamic_loader_implementation.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdynamic_loader_a-dynamic_loader_implementation.Tpo $(DEPDIR)/libdynamic_loader_a-dynamic_loader_implementation.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dynamic_loader_implementation.cc' object='libdynamic_loader_a-dynamic_loader_implementation.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -c -o libdynamic_loader_a-dynamic_loader_implementation.obj `if test -f 'dynamic_loader_implementation.cc'; then $(CYGPATH_W) 'dynamic_loader_implementation.cc'; else $(CYGPATH_W) '$(srcdir)/dynamic_loader_implementation.cc'; fi` libdynamic_loader_a-gmodule_implementation.o: gmodule_implementation.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -MT libdynamic_loader_a-gmodule_implementation.o -MD -MP -MF $(DEPDIR)/libdynamic_loader_a-gmodule_implementation.Tpo -c -o libdynamic_loader_a-gmodule_implementation.o `test -f 'gmodule_implementation.cc' || echo '$(srcdir)/'`gmodule_implementation.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdynamic_loader_a-gmodule_implementation.Tpo $(DEPDIR)/libdynamic_loader_a-gmodule_implementation.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gmodule_implementation.cc' object='libdynamic_loader_a-gmodule_implementation.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -c -o libdynamic_loader_a-gmodule_implementation.o `test -f 'gmodule_implementation.cc' || echo '$(srcdir)/'`gmodule_implementation.cc libdynamic_loader_a-gmodule_implementation.obj: gmodule_implementation.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -MT libdynamic_loader_a-gmodule_implementation.obj -MD -MP -MF $(DEPDIR)/libdynamic_loader_a-gmodule_implementation.Tpo -c -o libdynamic_loader_a-gmodule_implementation.obj `if test -f 'gmodule_implementation.cc'; then $(CYGPATH_W) 'gmodule_implementation.cc'; else $(CYGPATH_W) '$(srcdir)/gmodule_implementation.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdynamic_loader_a-gmodule_implementation.Tpo $(DEPDIR)/libdynamic_loader_a-gmodule_implementation.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gmodule_implementation.cc' object='libdynamic_loader_a-gmodule_implementation.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -c -o libdynamic_loader_a-gmodule_implementation.obj `if test -f 'gmodule_implementation.cc'; then $(CYGPATH_W) 'gmodule_implementation.cc'; else $(CYGPATH_W) '$(srcdir)/gmodule_implementation.cc'; fi` libdynamic_loader_a-posix_implementation.o: posix_implementation.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -MT libdynamic_loader_a-posix_implementation.o -MD -MP -MF $(DEPDIR)/libdynamic_loader_a-posix_implementation.Tpo -c -o libdynamic_loader_a-posix_implementation.o `test -f 'posix_implementation.cc' || echo '$(srcdir)/'`posix_implementation.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdynamic_loader_a-posix_implementation.Tpo $(DEPDIR)/libdynamic_loader_a-posix_implementation.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='posix_implementation.cc' object='libdynamic_loader_a-posix_implementation.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -c -o libdynamic_loader_a-posix_implementation.o `test -f 'posix_implementation.cc' || echo '$(srcdir)/'`posix_implementation.cc libdynamic_loader_a-posix_implementation.obj: posix_implementation.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -MT libdynamic_loader_a-posix_implementation.obj -MD -MP -MF $(DEPDIR)/libdynamic_loader_a-posix_implementation.Tpo -c -o libdynamic_loader_a-posix_implementation.obj `if test -f 'posix_implementation.cc'; then $(CYGPATH_W) 'posix_implementation.cc'; else $(CYGPATH_W) '$(srcdir)/posix_implementation.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdynamic_loader_a-posix_implementation.Tpo $(DEPDIR)/libdynamic_loader_a-posix_implementation.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='posix_implementation.cc' object='libdynamic_loader_a-posix_implementation.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -c -o libdynamic_loader_a-posix_implementation.obj `if test -f 'posix_implementation.cc'; then $(CYGPATH_W) 'posix_implementation.cc'; else $(CYGPATH_W) '$(srcdir)/posix_implementation.cc'; fi` libdynamic_loader_a-win32_implementation.o: win32_implementation.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -MT libdynamic_loader_a-win32_implementation.o -MD -MP -MF $(DEPDIR)/libdynamic_loader_a-win32_implementation.Tpo -c -o libdynamic_loader_a-win32_implementation.o `test -f 'win32_implementation.cc' || echo '$(srcdir)/'`win32_implementation.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdynamic_loader_a-win32_implementation.Tpo $(DEPDIR)/libdynamic_loader_a-win32_implementation.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='win32_implementation.cc' object='libdynamic_loader_a-win32_implementation.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -c -o libdynamic_loader_a-win32_implementation.o `test -f 'win32_implementation.cc' || echo '$(srcdir)/'`win32_implementation.cc libdynamic_loader_a-win32_implementation.obj: win32_implementation.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -MT libdynamic_loader_a-win32_implementation.obj -MD -MP -MF $(DEPDIR)/libdynamic_loader_a-win32_implementation.Tpo -c -o libdynamic_loader_a-win32_implementation.obj `if test -f 'win32_implementation.cc'; then $(CYGPATH_W) 'win32_implementation.cc'; else $(CYGPATH_W) '$(srcdir)/win32_implementation.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdynamic_loader_a-win32_implementation.Tpo $(DEPDIR)/libdynamic_loader_a-win32_implementation.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='win32_implementation.cc' object='libdynamic_loader_a-win32_implementation.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdynamic_loader_a_CXXFLAGS) $(CXXFLAGS) -c -o libdynamic_loader_a-win32_implementation.obj `if test -f 'win32_implementation.cc'; then $(CYGPATH_W) 'win32_implementation.cc'; else $(CYGPATH_W) '$(srcdir)/win32_implementation.cc'; fi` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: enblend-enfuse-4.2/src/dynamic_loader/posix_implementation.cc0000644000175000017500000000366512641706002021521 00000000000000/* * Copyright (C) 2013-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // See: http://pubs.opengroup.org/onlinepubs/9699919799/functions/dlopen.html #include "posix_implementation.h" PosixDynamicLoaderImplementation::PosixDynamicLoaderImplementation(const std::string& a_library_name) : super(a_library_name), handle_(nullptr) {} void PosixDynamicLoaderImplementation::open() { if (handle_) { throw super::error("already open"); } handle_ = dlopen(library_name().c_str(), RTLD_LAZY); if (!handle_) { throw super::error(dlerror()); } } void PosixDynamicLoaderImplementation::close() { if (!handle_) { throw super::error("not open"); } if (dlclose(handle_) != 0) { throw super::error(dlerror()); } } void* PosixDynamicLoaderImplementation::resolve(const std::string& symbol_name) const { if (!handle_) { throw super::error("not open"); } dlerror(); void* symbol = dlsym(handle_, symbol_name.c_str()); char* message = dlerror(); if (message != nullptr) { throw super::error(message); } if (symbol == nullptr) { throw super::error("symbol points nowhere"); } return symbol; } enblend-enfuse-4.2/src/dynamic_loader/dynamic_loader_implementation.cc0000644000175000017500000000054412603243001023313 00000000000000/* * This file is part of Enblend. * Licence details can be found in the file COPYING. */ #include "dynamic_loader_implementation.h" DynamicLoaderImplementation::DynamicLoaderImplementation(const std::string& a_library_name) : name_(a_library_name) {} const std::string& DynamicLoaderImplementation::library_name() const { return name_; } enblend-enfuse-4.2/src/dynamic_loader/dynamic_loader_implementation.h0000644000175000017500000000316212641706002023163 00000000000000/* * Copyright (C) 2013-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef DYNAMIC_LOADER_IMPLEMENTATION_H_INCLUDED #define DYNAMIC_LOADER_IMPLEMENTATION_H_INCLUDED #ifdef HAVE_CONFIG_H #include #endif #include #include class DynamicLoaderImplementation { public: DynamicLoaderImplementation() = delete; explicit DynamicLoaderImplementation(const std::string& a_library_name); virtual void open() = 0; virtual void close() = 0; virtual void* resolve(const std::string& a_symbol_name) const = 0; const std::string& library_name() const; virtual ~DynamicLoaderImplementation() {} struct error : public std::runtime_error { error(const std::string& a_message) : std::runtime_error(a_message) {} }; private: const std::string name_; }; #endif // DYNAMIC_LOADER_IMPLEMENTATION_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/dynamic_loader/gmodule_implementation.cc0000644000175000017500000000400412641706002021777 00000000000000/* * Copyright (C) 2013-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // See: https://developer.gnome.org/glib/unstable/glib-Dynamic-Loading-of-Modules.html #include "gmodule_implementation.h" GLibDynamicLoaderImplementation::GLibDynamicLoaderImplementation(const std::string& a_library_name) : super(a_library_name), module_(nullptr) {} void GLibDynamicLoaderImplementation::open() { if (module_) { throw super::error("already open"); } module_ = g_module_open(library_name().c_str(), G_MODULE_BIND_LAZY); if (!module_) { throw super::error(static_cast(g_module_error())); } } void GLibDynamicLoaderImplementation::close() { if (!module_) { throw super::error("not open"); } if (!g_module_close(module_)) { throw super::error(static_cast(g_module_error())); } } void* GLibDynamicLoaderImplementation::resolve(const std::string& symbol_name) const { if (!module_) { throw super::error("not open"); } void* symbol; if (!g_module_symbol(module_, symbol_name.c_str(), &symbol)) { throw super::error(static_cast(g_module_error())); } if (symbol == nullptr) { throw super::error("symbol points nowhere"); } return symbol; } enblend-enfuse-4.2/src/dynamic_loader/win32_implementation.h0000644000175000017500000000341412641706002021153 00000000000000/* * Copyright (C) 2015, 2016 Thomas Modes * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef WIN32_IMPLEMENTATION_H_INCLUDED #define WIN32_IMPLEMENTATION_H_INCLUDED #ifdef HAVE_CONFIG_H #include #endif #define NOMINMAX #include #include "dynamic_loader_implementation.h" class WinDynamicLoaderImplementation : public DynamicLoaderImplementation { typedef DynamicLoaderImplementation super; public: explicit WinDynamicLoaderImplementation(const std::string& a_library_name); void open(); void close(); void* resolve(const std::string& symbol_name) const; private: static const std::string GetLastErrorString(); HINSTANCE handle_; }; // class WinDynamicLoaderImplementation class ActualDynamicLoaderImplementation : public WinDynamicLoaderImplementation { public: explicit ActualDynamicLoaderImplementation(const std::string& a_library_name) : WinDynamicLoaderImplementation(a_library_name) {} }; // class ActualDynamicLoaderImplementation #endif // WIN32_IMPLEMENTATION_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/dynamic_loader/gmodule_implementation.h0000644000175000017500000000333112641706002021643 00000000000000/* * Copyright (C) 2013-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef GMODULE_IMPLEMENTATION_H_INCLUDED #define GMODULE_IMPLEMENTATION_H_INCLUDED #ifdef HAVE_CONFIG_H #include #endif #include #include "dynamic_loader_implementation.h" class GLibDynamicLoaderImplementation : public DynamicLoaderImplementation { typedef DynamicLoaderImplementation super; public: explicit GLibDynamicLoaderImplementation(const std::string& a_library_name); void open(); void close(); void* resolve(const std::string& symbol_name) const; private: GModule* module_; }; // class GLibDynamicLoaderImplementation class ActualDynamicLoaderImplementation : public GLibDynamicLoaderImplementation { public: explicit ActualDynamicLoaderImplementation(const std::string& a_library_name) : GLibDynamicLoaderImplementation(a_library_name) {} }; // class ActualDynamicLoaderImplementation #endif // GMODULE_IMPLEMENTATION_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/distance_transform_fh.cl0000644000175000017500000001147412641706002016650 00000000000000// Copyright (C) 2013-2016 Christoph L. Spiel // // This file is part of Enblend. // // Enblend 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. // // Enblend 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 Enblend; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA void manhattan_1d(global const float *restrict f, const int n, global float *restrict d) { d[0] = f[0]; #pragma unroll 8 for (int q = 1; q < n; ++q) { d[q] = min(f[q], d[q - 1] + 1.0f); } #pragma unroll 8 for (int q = n - 2; q >= 0; --q) { d[q] = min(d[q], d[q + 1] + 1.0f); } } kernel void manhattan_2d_columns(global float *restrict output, const int width, const int height, global float *restrict f_base, global float *restrict d_base) { const int x = get_global_id(0); if (x >= width) { return; } const int offset = x * max(width, height); global float *f = f_base + offset; global float *d = d_base + offset; for (int y = 0; y < height; y++) { f[y] = output[x + y * width]; } manhattan_1d(f, height, d); for (int y = 0; y < height; y++) { output[x + y * width] = d[y]; } } kernel void manhattan_2d_rows(global float *restrict output, const int width, const int height, global float *restrict f_base, global float *restrict d_base) { const int y = get_global_id(0); if (y >= height) { return; } const int offset = y * max(width, height); global float *f = f_base + offset; global float *d = d_base + offset; for (int x = 0; x < width; x++) { f[x] = output[x + y * width]; } manhattan_1d(f, width, d); for (int x = 0; x < width; x++) { output[x + y * width] = d[x]; } } //////////////////////////////////////////////////////////////////////////////// float square(const int n) { const float x = (float) n; return x * x; } void euclidean_1d(global const float *restrict f, const int n, global float *restrict d, global int *restrict v, global float *restrict z) { v[0] = 0; z[0] = -FLT_MAX; z[1] = +FLT_MAX; int k = 0; #pragma unroll 8 for (int q = 1; q < n; q++) { const float a = f[q] + square(q); float s = 0.5f * (a - (f[v[k]] + square(v[k]))) / (float) (q - v[k]); while (s <= z[k]) { k--; s = 0.5f * (a - (f[v[k]] + square(v[k]))) / (float) (q - v[k]); } k++; v[k] = q; z[k] = s; z[k + 1] = +FLT_MAX; } k = 0; #pragma unroll 8 for (int q = 0; q < n; q++) { while (z[k + 1] < (float) q) { k++; } d[q] = square(q - v[k]) + f[v[k]]; } } kernel void euclidean_2d_columns(global float *restrict output, const int width, const int height, global float *restrict f_base, global float *restrict d_base, global int *restrict v_base, global float *restrict z_base) { const int x = get_global_id(0); if (x >= width) { return; } const int offset = x * max(width, height); global float *f = f_base + offset; global float *d = d_base + offset; global int *v = v_base + offset; global float *z = z_base + offset; for (int y = 0; y < height; y++) { f[y] = output[x + y * width]; } euclidean_1d(f, height, d, v, z); for (int y = 0; y < height; y++) { output[x + y * width] = d[y]; } } kernel void euclidean_2d_rows(global float *restrict output, const int width, const int height, global float *restrict f_base, global float *restrict d_base, global int *restrict v_base, global float *restrict z_base) { const int y = get_global_id(0); if (y >= height) { return; } const int offset = y * max(width, height); global float *f = f_base + offset; global float *d = d_base + offset; global int *v = v_base + offset; global float *z = z_base + offset; for (int x = 0; x < width; x++) { f[x] = output[x + y * width]; } euclidean_1d(f, width, d, v, z); for (int x = 0; x < width; x++) { output[x + y * width] = native_sqrt(d[x]); } } enblend-enfuse-4.2/src/filespec.cc0000644000175000017500000010201112641706002014053 00000000000000/* * Copyright (C) 2009-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef _WIN32 #include #elif defined(__sun__) #include #include #else #include #include #endif #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include #endif #include "global.h" #include "error_message.h" #include "filenameparse.h" #include "filespec.h" #include "layer_selection.h" #include "selector.h" // How many lines at the beginning of a response file we check to // guess that it actually is a response file. #define RESPONSE_FILE_LINES_TO_CHECK 20U // Separator of key and value in a syntactic comment #define KEY_VALUE_SEPARATOR_CHAR ':' //< response-file-syntactic-comment-key-value-separator \char58 typedef std::pair key_value_pair; extern const std::string command; extern int Verbose; extern LayerSelectionHost LayerSelection; namespace enblend { // Print the (back-)trace of all response files opened so far. extern void unroll_trace(const FilePositionTrace& a_trace); TraceableFileName::TraceableFileName(const std::string& a_filename, const FilePositionTrace& a_trace, selector::Abstract* a_selector) : selector_(a_selector), filename_(a_filename), trace_(a_trace) {} TraceableFileName::~TraceableFileName() {} TraceableFileName* TraceableFileName::clone() const { return new TraceableFileName(*this); } const std::string& TraceableFileName::filename() const { return filename_; } const FilePositionTrace& TraceableFileName::trace() const { return trace_; } void TraceableFileName::unroll_trace() const { enblend::unroll_trace(trace_); } selector::Abstract* TraceableFileName::selector() const { return selector_; } TraceableFileNameAndLayer::TraceableFileNameAndLayer(const std::string& a_filename, const FilePositionTrace& a_trace, const std::string& a_layer_specification) : super(a_filename, a_trace, new selector::IndexedLayer(a_layer_specification)), layer_specification_(a_layer_specification) { #ifdef DEBUG_FILESPEC std::cout << "+ TraceableFileNameAndLayer(,,,): filename = <" << filename() << ">\n" << "+ TraceableFileNameAndLayer(,,,): layer_spec = <" << layer_spec() << ">\n" << "+ TraceableFileNameAndLayer(,,,): selector = <" << selector()->name() << ">\n"; #endif } TraceableFileNameAndLayer::TraceableFileNameAndLayer(const TraceableFileNameAndLayer& another) : super(another.filename(), another.trace(), new selector::IndexedLayer(another.layer_spec())), layer_specification_(another.layer_specification_) { #ifdef DEBUG_FILESPEC std::cout << "+ TraceableFileNameAndLayer(const&): filename = <" << filename() << ">\n" << "+ TraceableFileNameAndLayer(const&): layer_spec = <" << layer_spec() << ">\n" << "+ TraceableFileNameAndLayer(const&): selector = <" << selector()->name() << ">\n"; #endif } TraceableFileNameAndLayer::~TraceableFileNameAndLayer() { delete selector_; } TraceableFileNameAndLayer* TraceableFileNameAndLayer::clone() const { return new TraceableFileNameAndLayer(*this); } std::string TraceableFileNameAndLayer::layer_spec() const { return layer_specification_; } #ifdef _WIN32 /** Add all files which match filename to filelist. filename can * contain the wildcards '*' and '?' in the leaf position, but not in * the path. */ void glob_filename_win32(FileNameList& filelist, const std::string& filename) { // There has got to be an easier way... char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; char newFile[_MAX_PATH]; _splitpath(filename.c_str(), drive, dir, nullptr, nullptr); struct _finddata_t finddata; intptr_t findhandle = _findfirst(filename.c_str(), &finddata); if (findhandle != -1) { do { _splitpath(finddata.name, nullptr, nullptr, fname, ext); _makepath(newFile, drive, dir, fname, ext); filelist.push_back(std::string(newFile)); } while (_findnext(findhandle, &finddata) == 0); _findclose(findhandle); } } #endif // ANTICIPATED CHANGE: We already have the same function in // "common.h". static bool can_open_file(const std::string& aFilename) { errno = 0; std::ifstream file(aFilename.c_str()); if (!file) { std::cerr << command << ": failed to open \"" << aFilename << "\": " << errorMessage(errno) << "\n"; return false; } else { errno = 0; file.close(); if (file.fail()) { std::cerr << command << ": info: problems when closing \"" << aFilename << "\": " << errorMessage(errno) << "\n"; } return true; } } /** Convert a_string in a string that is printable. This is, it only * contains printable characters. */ std::string printable_string(const std::string& a_string) { std::string result; for (std::string::const_iterator c = a_string.begin(); c != a_string.end(); ++c) { if (isprint(*c)) { result.push_back(*c); } else { std::ostringstream oss; oss << "\\x" << std::hex << std::setw(2) << std::setfill('0') << (static_cast(*c) & 0xff); result.append(oss.str()); } } return result; } /** Answer line with leading and trailing whitespace removed. * Normalize blank lines and lines starting with a comment character * to an empty string. Remove all whitespace between the * response-file character and the following filename. */ std::string normalize_response_file_line(const std::string& line) { std::string result; std::string::size_type begin = line.find_first_not_of(WHITESPACE_CHARS); if (begin != std::string::npos && line[begin] != RESPONSE_FILE_COMMENT_CHAR) { const std::string::size_type end = line.find_last_not_of(WHITESPACE_CHARS); if (line[begin] == RESPONSE_FILE_PREFIX_CHAR) { begin = line.find_first_not_of(WHITESPACE_CHARS, begin + 1); result += RESPONSE_FILE_PREFIX_CHAR; } if (begin != std::string::npos) { result += line.substr(begin, end - begin + 1); } } return result; } static const key_value_pair empty_pair(std::make_pair(std::string(), std::string())); /** Answer the key-value pair in line or a pair of null strings, if * line does not define a syntactic comment. * * A syntactic comment line matches * ^[ \t]* # [ \t]* ([A-Za-z-]*) [ \t]* : [ \t]* ([^ \t]*) [ \t]*$ * where the first captured string is the key and second one is the * value. */ key_value_pair get_syntactic_comment(const std::string& line) { std::string::size_type begin = line.find_first_not_of(WHITESPACE_CHARS); if (begin != std::string::npos && line[begin] == RESPONSE_FILE_COMMENT_CHAR) { begin = line.find_first_not_of(WHITESPACE_CHARS, begin + 1); if (begin != std::string::npos) { std::string::size_type end = begin + 1; while (end < line.size() && (isalpha(line[end]) || line[end] == '-')) { ++end; } const std::string key = line.substr(begin, end - begin); begin = line.find_first_not_of(WHITESPACE_CHARS, end); if (begin != std::string::npos && line[begin] == KEY_VALUE_SEPARATOR_CHAR) { begin = line.find_first_not_of(WHITESPACE_CHARS, begin + 1); if (begin == std::string::npos) { return std::make_pair(key, std::string()); } else { end = line.find_last_not_of(WHITESPACE_CHARS); return std::make_pair(key, line.substr(begin, end - begin + 1)); } } else { return empty_pair; } } else { return empty_pair; } } else { return empty_pair; } } void unroll_trace(const FilePositionTrace& trace) { for (FilePositionTrace::const_iterator t = trace.begin(); t != trace.end(); ++t) { std::cerr << command << ": info: included from \"" << t->first << "\" line " << t->second << '\n'; } } class AbstractGlobbingAlgorithm { public: virtual FileNameList do_glob(const std::string& a_filename, const FilePositionTrace& trace) = 0; virtual ~AbstractGlobbingAlgorithm() {} virtual std::string description() const = 0; }; class LiteralGlobbingAlgorithm: public AbstractGlobbingAlgorithm { public: FileNameList do_glob(const std::string& a_filename, const FilePositionTrace& trace) { FileNameList result; result.push_back(a_filename); return result; } std::string description() const { return "Do not glob. Treat filenames as literals."; } }; #ifdef _WIN32 class WildcardGlobbingAlgorithm: public AbstractGlobbingAlgorithm { public: FileNameList do_glob(const std::string& a_filespec, const FilePositionTrace& trace) { FileNameList result; glob_filename_win32(result, a_filespec); return result; } std::string description() const { return "Glob only filenames, but not paths."; } }; #else class WildcardGlobbingAlgorithm: public AbstractGlobbingAlgorithm { public: WildcardGlobbingAlgorithm() : result_vector_(new glob_t) {} ~WildcardGlobbingAlgorithm() {delete result_vector_;} void run_glob(const std::string& a_filespec, const FilePositionTrace& trace, int flags) { errno = 0; if (glob(a_filespec.c_str(), flags, nullptr, // (*errfunc)(const char* filename, int error_code) result_vector_) != 0) { std::cerr << command << ": warning: globbing \"" << a_filespec << "\" failed: " << errorMessage(errno) << "\n"; unroll_trace(trace); } } void convert_to_list() { result_.clear(); for (char** path = result_vector_->gl_pathv; *path != nullptr; ++path) { result_.push_back(*path); } } FileNameList do_glob(const std::string& a_filespec, const FilePositionTrace& trace) { run_glob(a_filespec, trace, GLOB_ERR); convert_to_list(); globfree(result_vector_); return result_; } std::string description() const { return "Glob with wildcards '?', '*', '[', and ']'. See glob(7)."; } protected: glob_t* result_vector_; FileNameList result_; }; class ShellGlobbingAlgorithm : public WildcardGlobbingAlgorithm { public: FileNameList do_glob(const std::string& a_filespec, const FilePositionTrace& trace) { int flags = GLOB_ERR | GLOB_BRACE; #ifndef __sun__ flags |= GLOB_TILDE; #endif run_glob(a_filespec, trace, flags); convert_to_list(); globfree(result_vector_); return result_; } std::string description() const { return "Glob like UN*X shells do. Like \"wildcard\" plus '{', '}', and '~'. See glob(7)."; } }; #endif // _WIN32 #define MAKE_ALGORITHM(m_algorithm_pointer) \ std::make_pair(false, static_cast(m_algorithm_pointer)) #define MAKE_ALIAS(m_algorithm_pointer) \ std::make_pair(true, m_algorithm_pointer) class Globbing { // Map from the names of the algorithms or aliases to the // algorithms themselves. The boolean flag indicates whether we // point to the algorithm proper or the name is just an alias to // an existing algorithm. typedef std::map > algorithm_map; public: Globbing() : algorithm_name_("literal"), algorithm_(nullptr) { installed_algorithms_["literal"] = MAKE_ALGORITHM(new LiteralGlobbingAlgorithm); installed_algorithms_["wildcard"] = MAKE_ALGORITHM(new WildcardGlobbingAlgorithm); #ifndef _WIN32 installed_algorithms_["shell"] = MAKE_ALGORITHM(new ShellGlobbingAlgorithm); #endif setup_alias("literal", "none"); #ifndef _WIN32 setup_alias("shell", "sh"); #endif } ~Globbing() { for (algorithm_map::const_iterator i = installed_algorithms_.begin(); i != installed_algorithms_.end(); ++i) { if (!i->second.first) // not an alias { delete i->second.second; } } algorithm_ = nullptr; } const std::string& get_algorithm() const { return algorithm_name_; } bool set_algorithm(const std::string& an_algorithm_name) { algorithm_map::const_iterator a = installed_algorithms_.find(an_algorithm_name); if (a != installed_algorithms_.end()) { algorithm_name_ = a->first; algorithm_ = a->second.second; return true; } else { return false; } } FileNameList expand(const std::string& a_filename, const FilePositionTrace& trace) { if (algorithm_ == nullptr) { set_algorithm(algorithm_name_); } return algorithm_->do_glob(a_filename, trace); } algorithm_list get_known_algorithms() const { algorithm_list result; for (algorithm_map::const_iterator i = installed_algorithms_.begin(); i != installed_algorithms_.end(); ++i) { std::string description = i->second.second->description(); if (i->second.first) { description += " (alias)"; } result.push_back(make_pair(i->first, description)); } return result; } void setup_alias(const std::string& an_algorithm_name, const std::string& an_alias) { algorithm_map::const_iterator a = installed_algorithms_.find(an_algorithm_name); installed_algorithms_[an_alias] = MAKE_ALIAS(a->second.second); } private: std::string algorithm_name_; AbstractGlobbingAlgorithm* algorithm_; algorithm_map installed_algorithms_; }; algorithm_list known_globbing_algorithms() { Globbing glob; return glob.get_known_algorithms(); } //< RESPONSE_FILE_MAX_NESTING_LEVEL 63 #define RESPONSE_FILE_MAX_NESTING_LEVEL 63U struct TraceInfo { TraceInfo() : nesting_level(0U), current_directory(), file_position(), selection_algorithm() { selection_algorithm.push_front(LayerSelection.get_selector()); } unsigned nesting_level; const std::string current_directory; FilePositionTrace file_position; typedef std::list selection_algorithm_stack; selection_algorithm_stack selection_algorithm; }; #define LAYERSPEC_OPEN "[" //< LAYERSPEC_OPEN \char91 #define LAYERSPEC_CLOSE "]" //< LAYERSPEC_CLOSE \char93 #ifdef DEBUG_FILESPEC static std::string pretty_string_of_string_size_type(std::string::size_type a_size) { std::ostringstream stream; if (a_size == std::string::npos) { stream << "n/pos"; } else { stream << a_size; } return stream.str(); } #endif bool separate_filename_and_optional_layerspec(std::string& filename, std::string& layerspec, const std::string& filename_and_optional_layerspec) { const std::string::size_type layer_index_begin = filename_and_optional_layerspec.find_last_of(LAYERSPEC_OPEN); const std::string::size_type layer_index_end = filename_and_optional_layerspec.find_last_of(LAYERSPEC_CLOSE); bool has_layerspec; if (layer_index_begin != std::string::npos && layer_index_end != std::string::npos && layer_index_end + 1 == filename_and_optional_layerspec.length()) { std::string::size_type filename_end(layer_index_begin - 1); // Allow for whitespace between the filename proper and begin // of the later specification (LAYERSPEC_OPEN). while (std::isspace(filename_and_optional_layerspec[filename_end])) { --filename_end; } filename.assign(filename_and_optional_layerspec, 0, filename_end + 1); layerspec.assign(filename_and_optional_layerspec, layer_index_begin + 1, layer_index_end - layer_index_begin - 1); has_layerspec = true; } else { filename.assign(filename_and_optional_layerspec); layerspec.clear(); has_layerspec = false; } #ifdef DEBUG_FILESPEC std::cout << "+ separate_filename_and_optional_layerspec: layer_index_begin = " << pretty_string_of_string_size_type(layer_index_begin) << ", layer_index_end = " << pretty_string_of_string_size_type(layer_index_end) << ", length() = " << filename_and_optional_layerspec.length() << "\n" << "+ separate_filename_and_optional_layerspec: filename = <" << filename << ">, layerspec = <" << layerspec << ">\n" << "+ separate_filename_and_optional_layerspec -> " << has_layerspec << "\n"; #endif return has_layerspec; } static enblend::TraceableFileName* make_traceable_file_name_and_maybe_layer(const std::string& a_filename, const FilePositionTrace& a_file_position_trace, selector::Abstract* a_selector, bool has_layerspec, const std::string& a_layer_specification) { // We can have an empty layerspec ("[]"): has_layerspec == true && layerspec == "", // in contrast, without layerspec we get: has_layerspec == false && layerspec == "". return has_layerspec ? new enblend::TraceableFileNameAndLayer(a_filename, a_file_position_trace, a_layer_specification) : new enblend::TraceableFileName(a_filename, a_file_position_trace, a_selector); } void unfold_filename_iter(TraceableFileNameList& result, TraceInfo& trace_info, const std::string& filename_and_optional_layerspec) { std::string filename; std::string layerspec; const bool has_layerspec = separate_filename_and_optional_layerspec(filename, layerspec, filename_and_optional_layerspec); // Checking the nesting_lavel acts as an emergency break in the // case our usual recursion detection fails. if (trace_info.nesting_level > RESPONSE_FILE_MAX_NESTING_LEVEL) { std::cerr << command << ": warning: excessive nesting of " << trace_info.nesting_level << " levels of response files;\n" << command << ": warning: possible infinite recursion in \"" << printable_string(filename) << "\";\n" << command << ": warning: skipping further files\n"; unroll_trace(trace_info.file_position); return; } selector::Abstract* selector = trace_info.selection_algorithm.front(); if (filename.empty()) { std::cerr << command << ": info: empty filename\n"; if (!layerspec.empty()) { std::cerr << command << ": info: found only layer specification, missing filename\n"; } unroll_trace(trace_info.file_position); return; } else if (filename[0] == RESPONSE_FILE_PREFIX_CHAR) { const std::string response_filename(filename, 1); // filename alone #ifdef DEBUG_FILESPEC std::cout << "+ unfold_filename_iter: concatPath = <" << concatPath(trace_info.current_directory, response_filename) << ">\n"; #endif const std::string response_filepath = // filename in the right path enblend::canonicalizePath(enblend::isRelativePath(response_filename) ? concatPath(trace_info.current_directory, response_filename) : response_filename, false); for (FilePositionTrace::const_iterator t = trace_info.file_position.begin(); t != trace_info.file_position.end(); ++t) { if (t->first == response_filepath) { std::cerr << command << ": warning: response file \"" << printable_string(response_filepath) << "\" recursively\n"; unroll_trace(trace_info.file_position); return; } } #ifdef DEBUG_FILESPEC std::cout << "+ unfold_filename_iter: current_directory = " << trace_info.current_directory << "\n" << "+ unfold_filename_iter: response_filename = " << response_filename << "\n" << "+ unfold_filename_iter: response_filepath = " << response_filepath << "\n"; #endif if (Verbose >= VERBOSE_RESPONSE_FILES) { std::cerr << command << ": info: consulting response file \"" << printable_string(response_filepath) << "\"\n"; } if (!can_open_file(response_filepath)) { std::cerr << command << ": failed to open response file \"" << printable_string(response_filepath) << "\": " << errorMessage(errno) << "\n"; unroll_trace(trace_info.file_position); exit(1); } if (!maybe_response_file(response_filepath)) { std::cerr << command << ": warning: malformed response file \"" << printable_string(response_filepath) << "\"\n"; unroll_trace(trace_info.file_position); return; } std::ifstream response_file(response_filepath.c_str()); Globbing glob; // instatiating a new Glob object restores the defaults unsigned line_number = 0U; while (true) { std::string buffer; errno = 0; getline(response_file, buffer); if (!response_file.good()) { if (!buffer.empty()) { std::cerr << command << ": warning: ignoring last line of response file \"" << printable_string(response_filepath) << "\" line " << line_number + 1U << ",\n" << command << ": warning: because it does not end with a newline\n"; unroll_trace(trace_info.file_position); } break; } ++line_number; key_value_pair comment = get_syntactic_comment(buffer); enblend::to_lower(comment.first); enblend::to_lower(comment.second); if ((comment.first == "glob" || comment.first == "globbing" || comment.first == "filename-globbing") && !comment.second.empty()) { if (!glob.set_algorithm(comment.second)) { std::cerr << command << ": warning: requested unknown globbing algorithm \"" << comment.second << "\" in response file \"" << printable_string(response_filepath) << "\" line " << line_number << "\n" << command << ": note: will stick with algorithm \"" << glob.get_algorithm() << "\"\n"; unroll_trace(trace_info.file_position); } #ifdef DEBUG_FILESPEC std::cout << "+ unfold_filename_iter: new globbing algorithm = " << glob.get_algorithm() << "\n"; #endif } if (comment.first == "layer-selector" && !comment.second.empty()) { selector::algorithm_list::const_iterator new_selector = selector::find_by_name(comment.second); if (new_selector == selector::algorithms.end()) { std::cerr << command << ": warning: requested unknown default layer selector \"" << comment.second << "\" in response file \"" << printable_string(response_filepath) << "\" line " << line_number << "\n" << command << ": note: will stick with selector \"" << LayerSelection.name() << "\"\n"; unroll_trace(trace_info.file_position); } else { selector = new_selector->get(); #ifdef DEBUG_FILESPEC std::cout << "+ unfold_filename_iter: new layer selection algorithm = " << selector->name() << "\n"; #endif } } const std::string line(normalize_response_file_line(buffer)); if (line.empty()) { continue; } const std::string response_directory = extractDirname(response_filepath); #ifdef DEBUG_FILESPEC std::cout << "+ unfold_filename_iter: response_directory = " << response_directory << "\n"; #endif TraceableFileNameList partial_result; trace_info.selection_algorithm.push_front(selector); trace_info.file_position.push_front(std::make_pair(response_filepath, line_number)); ++trace_info.nesting_level; unfold_filename_iter(partial_result, trace_info, line); --trace_info.nesting_level; for (TraceableFileNameList::const_iterator p = partial_result.begin(); p != partial_result.end(); ++p) { const FileNameList expanded_partial_result = glob.expand((*p)->filename(), trace_info.file_position); for (FileNameList::const_iterator q = expanded_partial_result.begin(); q != expanded_partial_result.end(); ++q) { if (enblend::isRelativePath(*q)) { const std::string path = enblend::canonicalizePath(concatPath(response_directory, *q), false); #ifdef DEBUG_FILESPEC std::cout << "+ unfold_filename_iter: relative path\n" << "+ unfold_filename_iter: q = " << *q << "\n" << "+ unfold_filename_iter: path = <" << path << ">\n"; #endif result.insert(result.end(), make_traceable_file_name_and_maybe_layer(path, (*p)->trace(), (*p)->selector(), has_layerspec, layerspec)); } else { #ifdef DEBUG_FILESPEC std::cout << "+ unfold_filename_iter: absolute path\n" << "+ unfold_filename_iter: q = " << *q << "\n"; #endif result.insert(result.end(), make_traceable_file_name_and_maybe_layer(*q, (*p)->trace(), (*p)->selector(), has_layerspec, layerspec)); } } } for (auto x : partial_result) { delete x; } trace_info.file_position.pop_front(); trace_info.selection_algorithm.pop_front(); } if (!response_file.eof()) { std::cerr << command << ": warning: filesystem signals problems in response file \"" << printable_string(response_filepath) << "\" line " << line_number << ": " << errorMessage(errno) << "\n"; unroll_trace(trace_info.file_position); } } else { result.push_back(make_traceable_file_name_and_maybe_layer(filename, trace_info.file_position, selector, has_layerspec, layerspec)); } } void unfold_filename(TraceableFileNameList& result, const std::string& filename) { #ifdef _WIN32 // This stupid wannbe OS, lacking a shell that deserves the name, // passes unexpanded wildcards in filename. We ameliorate the // situation by doing some of the globbing ourselves; see // glob_filename_win32(). FileNameList initial_files; if (!filename.empty() && filename[0] == RESPONSE_FILE_PREFIX_CHAR) { initial_files.push_back(filename); } else { // Not a response file, so we expand wildcards. glob_filename_win32(initial_files, filename); } for (FileNameList::const_iterator i = initial_files.begin(); i != initial_files.end(); ++i) { TraceInfo trace_info; unfold_filename_iter(result, trace_info, *i); } #else TraceInfo trace_info; unfold_filename_iter(result, trace_info, filename); #endif #ifdef DEBUG_FILESPEC for (TraceableFileNameList::const_iterator i = result.begin(); i != result.end(); ++i) { std::cout << "+ unfold_filename: filename = <" << (*i)->filename() << ">, selector = " << (*i)->selector() << " -> \"" << (*i)->selector()->name() << "\"" << std::endl; for (FilePositionTrace::const_iterator j = (*i)->trace().begin(); j != (*i)->trace().end(); ++j) { std::cout << "+ unfold_filename: pos = (" << j->first << ", " << j->second << ")\n"; } } #endif } bool is_known_extension_to_vigra(const std::string& filename) { const std::string known_extensions = vigra::impexListExtensions(); const std::string extension(enblend::to_lower_copy(filename.substr(filename.rfind(".") + 1U))); return known_extensions.find(extension) != std::string::npos; } bool maybe_response_file(const std::string& filename) { std::ifstream file(filename.c_str()); if (file) { unsigned line_number = 0U; unsigned score = 0U; while (line_number < RESPONSE_FILE_LINES_TO_CHECK) { std::string buffer; getline(file, buffer); if (!file.good()) { break; } ++line_number; if (line_number == 1U) { const key_value_pair comment = get_syntactic_comment(buffer); if ((comment.first == "response-file" || comment.first == "enblend-response-file" || comment.first == "enfuse-response-file") && comment.second == "true") { return true; } } const std::string line(normalize_response_file_line(buffer)); if (line.empty()) { ++score; continue; } if (line[0] == RESPONSE_FILE_PREFIX_CHAR) { score += 2U; } std::string filename; std::string layerspec; separate_filename_and_optional_layerspec(filename, layerspec, line); if (is_known_extension_to_vigra(filename)) { score += 2U; } } #ifdef DEBUG_FILESPEC std::cout << "+ maybe_response_file: score = " << score << ", lines = " << line_number << "\n"; #endif return score >= line_number; } else { return false; } } } // namespace enblend enblend-enfuse-4.2/src/parameter.cc0000644000175000017500000002627112641706002014256 00000000000000/* * Copyright (C) 2015, 2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H #include #endif #include // isalnum(), isalpha() #include // errno #include // strtod(), strtol(), strtoul() #ifdef HAVE_UNORDERED_MAP #include #else #include #endif #include "parameter.h" namespace parameter { bool is_valid_identifier(const std::string& an_identifier) { if (an_identifier.size() == 0) { return false; } else if (!isalpha(an_identifier[0])) { return false; } else { for (std::string::const_iterator x = an_identifier.begin(); x != an_identifier.end(); ++x) { if (!(isalnum(*x) || *x == '_' || *x == '-')) { return false; } } } return true; } class ParameterValue { public: ParameterValue(); explicit ParameterValue(const std::string& a_string); ParameterValue(const ParameterValue& another_parameter_value); ParameterValue& operator=(const ParameterValue& another_parameter_value); virtual ~ParameterValue() {release_memory();} std::string as_string() const {return value_as_string_;} const char* as_c_string() const {return value_as_string_.c_str();} int as_integer() const; unsigned as_unsigned() const; double as_double() const; bool as_boolean() const; private: void initialize(); void initialize_integer(); void initialize_unsigned_integer(); void initialize_floating_point(); void initialize_boolean(); void copy_cached_values(const ParameterValue& a_parameter_value); void release_memory(); std::string value_as_string_; int* integer_; unsigned* unsigned_integer_; double* floating_point_; bool* boolean_; }; // end class ParameterValue ParameterValue::ParameterValue() : value_as_string_(std::string()), integer_(nullptr), unsigned_integer_(nullptr), floating_point_(nullptr), boolean_(nullptr) { initialize(); } ParameterValue::ParameterValue(const std::string& a_string) : value_as_string_(a_string), integer_(nullptr), unsigned_integer_(nullptr), floating_point_(nullptr), boolean_(nullptr) { initialize(); } ParameterValue::ParameterValue(const ParameterValue& another_parameter_value) : value_as_string_(another_parameter_value.value_as_string_), integer_(nullptr), unsigned_integer_(nullptr), floating_point_(nullptr), boolean_(nullptr) { copy_cached_values(another_parameter_value); } ParameterValue& ParameterValue::operator=(const ParameterValue& another_parameter_value) { if (this != &another_parameter_value) { value_as_string_ = another_parameter_value.value_as_string_; release_memory(); copy_cached_values(another_parameter_value); } return *this; } int ParameterValue::as_integer() const { if (integer_) { return *integer_; } else { throw conversion_error("cannot convert \"" + value_as_string_ + "\" to an integer"); } } unsigned ParameterValue::as_unsigned() const { if (unsigned_integer_) { return *unsigned_integer_; } else { throw conversion_error("cannot convert \"" + value_as_string_ + "\" to an unsigned integer"); } } double ParameterValue::as_double() const { if (floating_point_) { return *floating_point_; } else { throw conversion_error("cannot convert \"" + value_as_string_ + "\" to a floating-point number"); } } bool ParameterValue::as_boolean() const { if (boolean_) { return *boolean_; } else { throw conversion_error("cannot convert \"" + value_as_string_ + "\" to a boolean"); } } void ParameterValue::initialize() { initialize_integer(); initialize_unsigned_integer(); initialize_floating_point(); initialize_boolean(); } void ParameterValue::initialize_integer() { char* end; errno = 0; const int i = static_cast(strtol(value_as_string_.c_str(), &end, 10)); if (errno == 0 && *end == 0) { integer_ = new int; *integer_ = i; } } void ParameterValue::initialize_unsigned_integer() { char* end; errno = 0; const unsigned u = static_cast(strtoul(value_as_string_.c_str(), &end, 10)); if (errno == 0 && *end == 0) { unsigned_integer_ = new unsigned; *unsigned_integer_ = u; } } void ParameterValue::initialize_floating_point() { char* end; errno = 0; const double x = strtod(value_as_string_.c_str(), &end); if (errno == 0 && *end == 0) { floating_point_ = new double; *floating_point_ = x; } } void ParameterValue::initialize_boolean() { std::string s(value_as_string_); bool b; if (s.empty() || s == "0" || s == "f" || s == "false") { b = false; } else if (s == "1" || s == "t" || s == "true") { b = true; } else { char* end; errno = 0; b = strtol(value_as_string_.c_str(), &end, 10) != 0; if (errno != 0 || *end != 0) { return; } } boolean_ = new bool; *boolean_ = b; } void ParameterValue::copy_cached_values(const ParameterValue& a_parameter_value) { if (a_parameter_value.integer_) { integer_ = new int; *integer_ = *a_parameter_value.integer_; } if (a_parameter_value.unsigned_integer_) { unsigned_integer_ = new unsigned; *unsigned_integer_ = *a_parameter_value.unsigned_integer_; } if (a_parameter_value.floating_point_) { floating_point_ = new double; *floating_point_ = *a_parameter_value.floating_point_; } if (a_parameter_value.boolean_) { boolean_ = new bool; *boolean_ = *a_parameter_value.boolean_; } } void ParameterValue::release_memory() { delete integer_; delete unsigned_integer_; delete floating_point_; delete boolean_; } // // Parameter Map // #ifdef HAVE_UNORDERED_MAP typedef std::unordered_map parameter_map_t; #else typedef std::map parameter_map_t; #endif static parameter_map_t map; // Parameter Map - Modification void insert(const std::string& a_key, const std::string& a_value) { map.insert(parameter_map_t::value_type(a_key, ParameterValue(a_value))); } void erase(const std::string& a_key) { map.erase(a_key); } void erase_all() { map.clear(); } // Parameter Map - Query bool exists(const std::string& a_key) { return map.find(a_key) != map.end(); } std::string as_string(const std::string& a_key) { parameter_map_t::const_iterator x = map.find(a_key); if (x == map.end()) { throw not_found(a_key); } else { return x->second.as_string(); } } std::string as_string(const std::string& a_key, const std::string& a_default_value) { parameter_map_t::const_iterator x = map.find(a_key); if (x == map.end()) { return a_default_value; } else { return x->second.as_string(); } } int as_integer(const std::string& a_key) { parameter_map_t::iterator x = map.find(a_key); if (x == map.end()) { throw not_found(a_key); } else { return x->second.as_integer(); } } int as_integer(const std::string& a_key, int a_default_value) { parameter_map_t::iterator x = map.find(a_key); if (x == map.end()) { return a_default_value; } else { return x->second.as_integer(); } } unsigned as_unsigned(const std::string& a_key) { parameter_map_t::iterator x = map.find(a_key); if (x == map.end()) { throw not_found(a_key); } else { return x->second.as_unsigned(); } } unsigned as_unsigned(const std::string& a_key, unsigned a_default_value) { parameter_map_t::iterator x = map.find(a_key); if (x == map.end()) { return a_default_value; } else { return x->second.as_unsigned(); } } double as_double(const std::string& a_key) { parameter_map_t::iterator x = map.find(a_key); if (x == map.end()) { throw not_found(a_key); } else { return x->second.as_double(); } } double as_double(const std::string& a_key, double a_default_value) { parameter_map_t::iterator x = map.find(a_key); if (x == map.end()) { return a_default_value; } else { return x->second.as_double(); } } bool as_boolean(const std::string& a_key) { parameter_map_t::iterator x = map.find(a_key); if (x == map.end()) { throw not_found(a_key); } else { return x->second.as_boolean(); } } bool as_boolean(const std::string& a_key, bool a_default_value) { parameter_map_t::iterator x = map.find(a_key); if (x == map.end()) { return a_default_value; } else { return x->second.as_boolean(); } } } // end namespace parameter enblend-enfuse-4.2/src/Sig.pm0000644000175000017500000000074512231147646013055 00000000000000# name: Sig.pm # synopsis: signature generation # author: Dr. Christoph L. Spiel # perl version: 5.10.0 # This file is part of Enblend. # Licence details can be found in the file COPYING. package Sig; use strict; use warnings; use DefaultSig; our @ISA = qw(DefaultSig); # See the base class, DefaultSig, for available methods and the # default definition of signature(). # sub signature { # my $self = shift; # # return "My signature ..."; # } 1; enblend-enfuse-4.2/src/postoptimizer.h0000644000175000017500000005577212641706002015100 00000000000000/* * Copyright (C) 2011-2016 Mikolaj Leszczynski * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __POSTOPTIMIZER_H__ #define __POSTOPTIMIZER_H__ #include #include "rect2d.hxx" #include "stride.hxx" #include "anneal.h" #include "masktypedefs.h" #include "mask.h" using vigra::functor::Arg1; using vigra::functor::Arg2; using vigra::functor::Arg3; using vigra::functor::ifThenElse; using vigra::functor::Param; using vigra::functor::UnaryFunctor; namespace enblend { // Base abstract class for optimizer plugins template class PostOptimizer { public: PostOptimizer() = delete; PostOptimizer(MismatchImageType* aMismatchImage, VisualizeImageType* aVisualizeImage, vigra::Size2D* aMismatchImageSize, int* aMismatchImageStride, vigra::Diff2D* aUVBBStrideOffset, ContourVector* someContours, const vigra::Rect2D* aUBB, vigra::Rect2D* aVBB, std::vector* someParameters, const AlphaType* aWhiteAlpha, const AlphaType* aBlackAlpha, const vigra::Rect2D* aUVBB) : mismatchImage(aMismatchImage), visualizeImage(aVisualizeImage), mismatchImageSize(aMismatchImageSize), mismatchImageStride(aMismatchImageStride), uvBBStrideOffset(aUVBBStrideOffset), contours(someContours), uBB(aUBB), vBB(aVBB), parameters(*someParameters), whiteAlpha(aWhiteAlpha), blackAlpha(aBlackAlpha), uvBB(aUVBB) {} PostOptimizer(PostOptimizer* other) = delete; PostOptimizer& operator=(const PostOptimizer &other) = delete; virtual void runOptimizer() {} virtual ~PostOptimizer() {} protected: virtual void configureOptimizer() {} MismatchImageType* mismatchImage; VisualizeImageType* visualizeImage; vigra::Size2D* mismatchImageSize; int* mismatchImageStride; vigra::Diff2D* uvBBStrideOffset; ContourVector* contours; const vigra::Rect2D* uBB; vigra::Rect2D* vBB; std::vector parameters; const AlphaType* whiteAlpha; const AlphaType* blackAlpha; const vigra::Rect2D* uvBB; }; // Optimizer strategy 1: Anneal optimizer template class AnnealOptimizer : public PostOptimizer { public: typedef PostOptimizer super; AnnealOptimizer() = delete; AnnealOptimizer(MismatchImageType* mismatchImage, VisualizeImageType* visualizeImage, vigra::Size2D* mismatchImageSize, int* mismatchImageStride, vigra::Diff2D* uvBBStrideOffset, ContourVector* contours, const vigra::Rect2D* uBB, vigra::Rect2D* vBB, std::vector* parameters, const AlphaType* whiteAlpha, const AlphaType* blackAlpha, const vigra::Rect2D* uvBB) : super(mismatchImage, visualizeImage, mismatchImageSize, mismatchImageStride, uvBBStrideOffset, contours, uBB, vBB, parameters, whiteAlpha, blackAlpha, uvBB) {} AnnealOptimizer(AnnealOptimizer* other) = delete; AnnealOptimizer& operator=(const AnnealOptimizer &other) = delete; virtual void runOptimizer() { configureOptimizer(); int segmentNumber; for (ContourVector::iterator currentContour = (*this->contours).begin(); currentContour != (*this->contours).end(); ++currentContour) { segmentNumber = 0; for (Contour::iterator currentSegment = (*currentContour)->begin(); currentSegment != (*currentContour)->end(); ++currentSegment, ++segmentNumber) { Segment* snake = *currentSegment; if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << command << ": info: Annealing Optimizer, s" << segmentNumber << ":"; std::cerr.flush(); } if (snake->empty()) { std::cerr << std::endl << command << ": warning: seam s" << segmentNumber - 1 << " is a tiny closed contour and was removed before optimization" << std::endl; continue; } annealSnake(this->mismatchImage, OptimizerWeights, snake, this->visualizeImage); // Post-process annealed vertices Segment::iterator lastVertex = std::prev(snake->end()); for (Segment::iterator vertexIterator = snake->begin(); vertexIterator != snake->end();) { if (vertexIterator->first && (*this->mismatchImage)[vertexIterator->second] == vigra::NumericTraits::max()) { // Vertex is still in max-cost region. Delete it. if (vertexIterator == snake->begin()) { snake->pop_front(); vertexIterator = snake->begin(); } else { vertexIterator = snake->erase(std::next(lastVertex)); } bool needsBreak = false; if (vertexIterator == snake->end()) { vertexIterator = snake->begin(); needsBreak = true; } // vertexIterator now points to next entry. // It is conceivable but very unlikely that every vertex in a closed contour // ended up in the max-cost region after annealing. if (snake->empty()) { break; } if (!(lastVertex->first || vertexIterator->first)) { // We deleted an entire range of moveable points between two nonmoveable points. // insert dummy point after lastVertex so dijkstra can work over this range. if (vertexIterator == snake->begin()) { snake->push_front(std::make_pair(true, vertexIterator->second)); lastVertex = snake->begin(); } else { lastVertex = snake->insert(std::next(lastVertex), std::make_pair(true, vertexIterator->second)); } } if (needsBreak) { break; } } else { lastVertex = vertexIterator; ++vertexIterator; } } if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << std::endl; } // Print an explanation if every vertex in a closed contour ended up in the // max-cost region after annealing. // FIXME: explain how to fix this problem in the error message! if (snake->empty()) { std::cerr << std::endl << command << ": seam s" << segmentNumber - 1 << " is a tiny closed contour and was removed after optimization" << std::endl; } } } } virtual ~AnnealOptimizer() {} private: void configureOptimizer() { // Areas other than intersection region have maximum cost. vigra::omp::combineThreeImages(vigra_ext::stride(*this->mismatchImageStride, *this->mismatchImageStride, vigra_ext::apply(*this->uvBB, srcImageRange(*this->whiteAlpha))), vigra_ext::stride(*this->mismatchImageStride, *this->mismatchImageStride, vigra_ext::apply(*this->uvBB, srcImage(*this->blackAlpha))), srcIter((this->mismatchImage)->upperLeft() + *this->uvBBStrideOffset), destIter((this->mismatchImage)->upperLeft() + *this->uvBBStrideOffset), ifThenElse(Arg1() & Arg2(), Arg3(), Param(vigra::NumericTraits::max()))); } }; // Optimizer Strategy 2: Dijkstra optimizer template class DijkstraOptimizer : public PostOptimizer { public: typedef PostOptimizer super; DijkstraOptimizer() = delete; DijkstraOptimizer(MismatchImageType* mismatchImage, VisualizeImageType* visualizeImage, vigra::Size2D* mismatchImageSize, int* mismatchImageStride, vigra::Diff2D* uvBBStrideOffset, ContourVector* contours, const vigra::Rect2D* uBB, vigra::Rect2D* vBB, std::vector* parameters, const AlphaType* whiteAlpha, const AlphaType* blackAlpha, const vigra::Rect2D* uvBB) : super(mismatchImage, visualizeImage, mismatchImageSize, mismatchImageStride, uvBBStrideOffset, contours, uBB, vBB, parameters, whiteAlpha, blackAlpha, uvBB) {} DijkstraOptimizer(DijkstraOptimizer* other) = delete; DijkstraOptimizer& operator=(const DijkstraOptimizer &other) = delete; virtual void runOptimizer() { configureOptimizer(); vigra::Rect2D withinMismatchImage(*this->mismatchImageSize); int segmentNumber; if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << command << ": info: Dijkstra Optimizer:"; std::cerr.flush(); } // Use Dijkstra to route between moveable snake vertices over mismatchImage. for (ContourVector::iterator currentContour = (*this->contours).begin(); currentContour != (*this->contours).end(); ++currentContour) { segmentNumber = 0; for (Contour::iterator currentSegment = (*currentContour)->begin(); currentSegment != (*currentContour)->end(); ++currentSegment, ++segmentNumber) { Segment* snake = *currentSegment; if (snake->empty()) { continue; } if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << " s" << segmentNumber; std::cerr.flush(); } for (Segment::iterator currentVertex = snake->begin(); ; ) { Segment::iterator nextVertex = currentVertex; ++nextVertex; if (nextVertex == snake->end()) { nextVertex = snake->begin(); } if (currentVertex->first || nextVertex->first) { // Find shortest path between these points const vigra::Point2D currentPoint = currentVertex->second; const vigra::Point2D nextPoint = nextVertex->second; vigra::Rect2D pointSurround(currentPoint, vigra::Size2D(1, 1)); pointSurround |= vigra::Rect2D(nextPoint, vigra::Size2D(1, 1)); pointSurround.addBorder(DijkstraRadius); pointSurround &= withinMismatchImage; // Make BasicImage to hold pointSurround portion of mismatchImage. // min cost path needs inexpensive random access to cost image. vigra::BasicImage mismatchROIImage(pointSurround.size()); vigra::copyImage(vigra_ext::apply(pointSurround, srcImageRange(*this->mismatchImage)), destImage(mismatchROIImage)); std::vector* shortPath = minCostPath(srcImageRange(mismatchROIImage), vigra::Point2D(nextPoint - pointSurround.upperLeft()), vigra::Point2D(currentPoint - pointSurround.upperLeft())); if (shortPath->empty()) { std::cerr << command << ": warning: unable to run Dijkstra optimizer\n" << command << ": note: seam-line end point outside of cost-image\n" << command << ": note: contour #" << (currentContour - (*this->contours).begin()) + 1U << " of " << (*this->contours).size() << ", segment #" << (currentSegment - (*currentContour)->begin()) + 1U << " of " << (*currentContour)->size() << ", vertex #" << std::accumulate(snake->begin(), currentVertex, 1U, [](unsigned a, SegmentPoint) {return a + 1U;}) << " of " << snake->size() << std::endl; } for (std::vector::iterator shortPathPoint = shortPath->begin(); shortPathPoint != shortPath->end(); ++shortPathPoint) { snake->insert(std::next(currentVertex), std::make_pair(false, *shortPathPoint + pointSurround.upperLeft())); if (this->visualizeImage) { (*this->visualizeImage)[*shortPathPoint + pointSurround.upperLeft()] = VISUALIZE_SHORT_PATH_VALUE; } } delete shortPath; if (this->visualizeImage) { const vigra::Size2D size(*this->visualizeImage->size()); const vigra::Rect2D valid_region(size); if (valid_region.contains(currentPoint)) { (*this->visualizeImage)[currentPoint] = currentVertex->first ? VISUALIZE_FIRST_VERTEX_VALUE : VISUALIZE_NEXT_VERTEX_VALUE; } if (valid_region.contains(nextPoint)) { (*this->visualizeImage)[nextPoint] = nextVertex->first ? VISUALIZE_FIRST_VERTEX_VALUE : VISUALIZE_NEXT_VERTEX_VALUE; } } } currentVertex = nextVertex; if (nextVertex == snake->begin()) { break; } } } } if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << std::endl; } } virtual ~DijkstraOptimizer() {} private: void configureOptimizer() { vigra::omp::combineThreeImages(vigra_ext::stride(*this->mismatchImageStride, *this->mismatchImageStride, vigra_ext::apply(*this->uvBB, srcImageRange(*this->whiteAlpha))), vigra_ext::stride(*this->mismatchImageStride, *this->mismatchImageStride, vigra_ext::apply(*this->uvBB, srcImage(*this->blackAlpha))), srcIter((this->mismatchImage)->upperLeft() + *this->uvBBStrideOffset), destIter((this->mismatchImage)->upperLeft() + *this->uvBBStrideOffset), ifThenElse(!(Arg1() || Arg2()), Param(vigra::NumericTraits::one()), Arg3())); } }; template class OptimizerChain : public PostOptimizer { public: typedef PostOptimizer super; typedef std::vector optimizer_list_t; typedef typename optimizer_list_t::iterator optimizer_list_iterator; OptimizerChain() = delete; OptimizerChain(MismatchImageType* mismatchImage, VisualizeImageType* visualizeImage, vigra::Size2D* mismatchImageSize, int* mismatchImageStride, vigra::Diff2D* uvBBStrideOffset, ContourVector* contours, const vigra::Rect2D* uBB, vigra::Rect2D* vBB, std::vector* parameters, const AlphaType* whiteAlpha, const AlphaType* blackAlpha, const vigra::Rect2D* uvBB) : super(mismatchImage, visualizeImage, mismatchImageSize, mismatchImageStride, uvBBStrideOffset, contours, uBB, vBB, parameters, whiteAlpha, blackAlpha, uvBB), currentOptimizer(0) {} OptimizerChain(OptimizerChain* other) = delete; OptimizerChain& operator=(const OptimizerChain &other) = delete; void addOptimizer(const std::string& anOptimizerName) { typedef enum {NO_OPTIMIZER, ANNEAL_OPTIMIZER, DIJKSTRA_OPTIMIZER} optimizer_id_t; optimizer_id_t id = NO_OPTIMIZER; if (anOptimizerName == "anneal") { id = ANNEAL_OPTIMIZER; } else if (anOptimizerName == "dijkstra") { id = DIJKSTRA_OPTIMIZER; } switch (id) { case ANNEAL_OPTIMIZER: optimizerList.push_back(new AnnealOptimizer (this->mismatchImage, this->visualizeImage, this->mismatchImageSize, this->mismatchImageStride, this->uvBBStrideOffset, this->contours, this->uBB, this->vBB, &this->parameters, this->whiteAlpha, this->blackAlpha, this->uvBB)); break; case DIJKSTRA_OPTIMIZER: optimizerList.push_back(new DijkstraOptimizer (this->mismatchImage, this->visualizeImage, this->mismatchImageSize, this->mismatchImageStride, this->uvBBStrideOffset, this->contours, this->uBB, this->vBB, &this->parameters, this->whiteAlpha, this->blackAlpha, this->uvBB)); break; default: throw never_reached("switch control expression \"id\" (optimizer selection) out of range"); } } // Run every optimizer added to the list sequentially in FIFO // order. void runOptimizerChain() { std::for_each(optimizerList.begin(), optimizerList.end(), [](typename optimizer_list_t::value_type x) {x->runOptimizer();}); } // Run current optimizer and increment the counter provided // there are still optimizers in the chain to run. Used // primarily for debugging purposes. For other uses, use the // runOptimizerChain() function. void runCurrentOptimizer() { if (currentOptimizer < optimizerList.size()) { optimizerList[currentOptimizer]->runOptimizer(); ++currentOptimizer; } } virtual ~OptimizerChain() { std::for_each(optimizerList.begin(), optimizerList.end(), [](typename optimizer_list_t::value_type x) {delete x;}); } private: optimizer_list_t optimizerList; size_t currentOptimizer; }; } // namespace enblend #endif /* __POSTOPTIMIZER_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/alternativepercentage.h0000644000175000017500000000536212641706002016512 00000000000000/* * Copyright (C) 2015-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef ALTERNATIVEPERCENTAGE_H_INCLUDED_ #define ALTERNATIVEPERCENTAGE_H_INCLUDED_ #ifdef HAVE_CONFIG_H #include #endif #include class AlternativePercentage { public: AlternativePercentage() = delete; AlternativePercentage(double a_value, bool is_percentage); virtual ~AlternativePercentage() {} virtual double value() const {return value_;} bool is_percentage() const {return is_percentage_;} virtual void set_value(double a_value); void set_percentage(bool is_percentage); virtual std::string str() const; template bool is_effective() const { return value_ > 0.0 && ((is_percentage() && value() < 100.0) || (!is_percentage() && value() < vigra::NumericTraits::max())); } template t instantiate() const { const double max {static_cast(vigra::NumericTraits::max())}; return is_percentage() ? value() * max / 100.0 : value(); } private: double value_; bool is_percentage_; }; class CompactifiedAlternativePercentage : public AlternativePercentage { public: CompactifiedAlternativePercentage() = delete; CompactifiedAlternativePercentage(double a_value, bool is_percentage); template bool is_effective() const { return value() != 0.0 && ((is_percentage() && std::abs(value()) != 100.0) || (!is_percentage() && value() != vigra::NumericTraits::max())); } template t instantiate() const { const double max {static_cast(vigra::NumericTraits::max())}; if (is_percentage()) { return (value() >= 0.0 ? value() : 100.0 + value()) * max / 100.0; } else { return value() >= 0.0 ? value() : max + value(); } } }; #endif // ALTERNATIVEPERCENTAGE_H_INCLUDED_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/stride.hxx0000644000175000017500000001504112641704341014007 00000000000000#ifndef STRIDE_HXX_INCLUDED #define STRIDE_HXX_INCLUDED #include namespace vigra_ext { namespace detail { inline static vigra::Diff2D strided_size(int an_xstride, int a_ystride, vigra::Diff2D a_size) { if (a_size.x % an_xstride != 0) { a_size.x += an_xstride - a_size.x % an_xstride; } if (a_size.y % a_ystride != 0) { a_size.y += a_ystride - a_size.y % a_ystride; } a_size.x /= an_xstride; a_size.y /= a_ystride; return a_size; } template inline static int iterator_width(iterator an_image_iterator) { iterator next_line(an_image_iterator); next_line.y += 1; return next_line[0] - an_image_iterator[0]; } } // namespace detail template inline static vigra::triple, vigra::StridedImageIterator, accessor> stride(int an_xstride, int a_ystride, const vigra::triple, vigra::BasicImageIterator, accessor>& an_image) { typedef vigra::StridedImageIterator strided_iterator; const vigra::Diff2D size(detail::strided_size(an_xstride, a_ystride, an_image.second - an_image.first)); const strided_iterator base(strided_iterator(an_image.first[0], detail::iterator_width(an_image.first), an_xstride, a_ystride)); return vigra::make_triple(base, base + size, an_image.third); } template inline static vigra::triple, vigra::ConstStridedImageIterator, accessor> stride(int an_xstride, int a_ystride, const vigra::triple, vigra::ConstImageIterator, accessor>& an_image) { typedef vigra::ConstStridedImageIterator constant_strided_iterator; const vigra::Diff2D size(detail::strided_size(an_xstride, a_ystride, an_image.second - an_image.first)); const constant_strided_iterator base(an_image.first[0], detail::iterator_width(an_image.first), an_xstride, a_ystride); return vigra::make_triple(base, base + size, an_image.third); } template inline static std::pair, accessor> stride(int an_xstride, int a_ystride, const std::pair, accessor>& an_image) { typedef vigra::StridedImageIterator strided_iterator; return std::make_pair(strided_iterator(an_image.first[0], detail::iterator_width(an_image.first), an_xstride, a_ystride), an_image.second); } template inline static std::pair, accessor> stride(int an_xstride, int a_ystride, const std::pair, accessor>& an_image) { typedef vigra::StridedImageIterator strided_iterator; return std::make_pair(strided_iterator(an_image.first[0], detail::iterator_width(an_image.first), an_xstride, a_ystride), an_image.second); } template inline static vigra::triple, vigra::ConstStridedImageIterator, accessor> stride(int an_xstride, int a_ystride, const vigra::triple, vigra::ConstBasicImageIterator, accessor>& an_image) { typedef vigra::ConstStridedImageIterator constant_strided_iterator; const vigra::Diff2D size(detail::strided_size(an_xstride, a_ystride, an_image.second - an_image.first)); const constant_strided_iterator base(constant_strided_iterator(an_image.first[0], detail::iterator_width(an_image.first), an_xstride, a_ystride)); return vigra::make_triple(base, base + size, an_image.third); } template inline static std::pair, accessor> stride(int an_xstride, int a_ystride, const std::pair, accessor>& an_image) { typedef vigra::ConstStridedImageIterator constant_strided_iterator; return std::make_pair(constant_strided_iterator(an_image.first[0], detail::iterator_width(an_image.first), an_xstride, a_ystride), an_image.second); } template inline static std::pair, accessor> stride(int an_xstride, int a_ystride, const std::pair, accessor>& an_image) { typedef vigra::ConstStridedImageIterator constant_strided_iterator; return std::make_pair(constant_strided_iterator(an_image.first[0], detail::iterator_width(an_image.first), an_xstride, a_ystride), an_image.second); } } // namespace vigra_ext #endif // STRIDE_HXX_INCLUDED enblend-enfuse-4.2/src/assemble.h0000644000175000017500000003731012641706002013727 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ASSEMBLE_H__ #define __ASSEMBLE_H__ #ifdef HAVE_CONFIG_H #include #endif #include #include #ifndef _WIN32 #include #endif #include #include #include #include #include #include #include #include "functoraccessor.hxx" #include "common.h" #include "fixmath.h" namespace enblend { template struct IntegralSelect {typedef T Result;}; template <> struct IntegralSelect {typedef vigra::UInt32 Result;}; template <> struct IntegralSelect {typedef vigra::UInt32 Result;}; template <> struct IntegralSelect > { typedef vigra::RGBValue Result; }; template <> struct IntegralSelect > { typedef vigra::RGBValue Result; }; template void exportImagePreferablyWithAlpha(const ImageType* image, const AlphaType* mask, const AlphaAccessor& mask_accessor, const vigra::ImageExportInfo& outputImageInfo) { try { vigra::exportImageAlpha(srcImageRange(*image), srcIter(mask->upperLeft(), mask_accessor), outputImageInfo); } catch (std::exception& e) { std::cerr << command << ": warning: must fall back to export image without alpha channel" << std::endl; #ifdef DEBUG std::cerr << "+ exportImagePreferablyWithAlpha: exception description follows..." << e.what(); #endif exportImage(srcImageRange(*image), outputImageInfo); } OutputIsValid = true; } /** Write output images. */ template void checkpoint(const std::pair& p, const vigra::ImageExportInfo& outputImageInfo) { typedef typename ImageType::PixelType ImagePixelType; typedef typename EnblendNumericTraits::ImagePixelComponentType ImagePixelComponentType; typedef typename AlphaType::Accessor AlphaAccessor; typedef typename AlphaType::PixelType AlphaPixelType; ImageType* image = p.first; AlphaType* mask = p.second; vigra_ext::ReadFunctorAccessor, AlphaAccessor> ata(vigra::Threshold (AlphaTraits::zero(), AlphaTraits::zero(), AlphaTraits::max(), AlphaTraits::zero()), mask->accessor()); const std::pair outputRange = enblend::rangeOfPixelType(outputImageInfo.getPixelType()); const ImagePixelComponentType inputMin = vigra::NumericTraits::isIntegral::asBool ? vigra::NumericTraits::min() : 0.0; const ImagePixelComponentType inputMax = vigra::NumericTraits::isIntegral::asBool ? vigra::NumericTraits::max() : 1.0; #ifdef DEBUG std::cerr << "+ checkpoint: input range: (" << static_cast(inputMin) << ", " << static_cast(inputMax) << ")\n" << "+ checkpoint: output range: (" << outputRange.first << ", " << outputRange.second << ")" << std::endl; #endif if (inputMin <= outputRange.first && inputMax >= outputRange.second) { if (inputMin == outputRange.first && inputMax == outputRange.second) { // No rescaling is necessary here: We skip the redundant // transformation of the input to the output range and // leave the channel width alone. ; #ifdef DEBUG std::cerr << "+ checkpoint: leaving channel width alone" << std::endl; #endif exportImagePreferablyWithAlpha(image, mask, ata, outputImageInfo); } else { const std::string pixel_type(enblend::to_lower_copy(std::string(outputImageInfo.getPixelType()))); std::cerr << command << ": info: narrowing channel width for output as \"" << pixel_type << "\"" << std::endl; ImageType lowDepthImage(image->width(), image->height()); vigra::omp::transformImage(srcImageRange(*image), destImage(lowDepthImage), vigra::linearRangeMapping(ImagePixelType(inputMin), ImagePixelType(inputMax), ImagePixelType(outputRange.first), ImagePixelType(outputRange.second))); exportImagePreferablyWithAlpha(&lowDepthImage, mask, ata, outputImageInfo); } } else { const std::string pixel_type(enblend::to_lower_copy(std::string(outputImageInfo.getPixelType()))); std::cerr << command << ": info: rescaling floating-point data for output as \"" << pixel_type << "\"" << std::endl; typedef typename IntegralSelect::Result IntegralPixelType; typedef typename EnblendNumericTraits::ImagePixelComponentType IntegralPixelComponentType; IMAGETYPE integralImage(image->width(), image->height()); vigra_ext::ReadFunctorAccessor, AlphaAccessor> ata(vigra::Threshold (AlphaTraits::zero(), AlphaTraits::zero(), AlphaTraits::max(), AlphaTraits::zero()), mask->accessor()); vigra::omp::transformImage(srcImageRange(*image), destImage(integralImage), vigra::linearRangeMapping(ImagePixelType(inputMin), ImagePixelType(inputMax), IntegralPixelType(outputRange.first), IntegralPixelType(outputRange.second))); exportImagePreferablyWithAlpha(&integralImage, mask, ata, outputImageInfo); } } template void import(const vigra::ImageImportInfo& info, const std::pair& image, const std::pair& alpha) { typedef typename DestIterator::PixelType ImagePixelType; typedef typename EnblendNumericTraits::ImagePixelComponentType ImagePixelComponentType; typedef typename AlphaIterator::PixelType AlphaPixelType; const vigra::Diff2D extent = vigra::Diff2D(info.width(), info.height()); const std::string pixelType = info.getPixelType(); const range_t inputRange = enblend::rangeOfPixelType(pixelType); if (info.numExtraBands() > 0) { // Threshold the alpha mask so that all pixels are either // contributing or not contributing. vigra_ext::WriteFunctorAccessor, AlphaAccessor> ata(vigra::Threshold (inputRange.second / 2, inputRange.second, AlphaTraits::zero(), AlphaTraits::max()), alpha.second); vigra::importImageAlpha(info, image, vigra::destIter(alpha.first, ata)); } else { // Import image without alpha. Initialize the alpha image to 100%. importImage(info, image.first, image.second); initImage(srcIterRange(alpha.first, alpha.first + extent, alpha.second), AlphaTraits::max()); } // Performance Optimization: Transform only if ranges do not // match. const double min = vigra::NumericTraits::isIntegral::asBool ? static_cast(vigra::NumericTraits::min()) : 0.0; const double max = vigra::NumericTraits::isIntegral::asBool ? static_cast(vigra::NumericTraits::max()) : 1.0; if (inputRange.first != min || inputRange.second != max) { vigra::omp::transformImage(srcIterRange(image.first, image.first + extent, image.second), vigra::destIter(image.first, image.second), vigra::linearRangeMapping(ImagePixelType(inputRange.first), ImagePixelType(inputRange.second), ImagePixelType(min), ImagePixelType(max))); } } /** Find images that do not overlap and assemble them into one image. * Uses a greedy heuristic. * Removes used images from given list of ImageImportInfos. * Returns an ImageImportInfo for the temporary file. * memory xsection = 2 * (ImageType*inputUnion + AlphaType*inputUnion) */ template std::pair assemble(std::list& imageInfoList, vigra::Rect2D& inputUnion, vigra::Rect2D& bb) { typedef typename AlphaType::traverser AlphaIteratorType; typedef typename AlphaType::Accessor AlphaAccessor; // No more images to assemble? if (imageInfoList.empty()) { return std::pair(static_cast(nullptr), static_cast(nullptr)); } // Create an image to assemble input images into. ImageType* image = new ImageType(inputUnion.size()); AlphaType* imageA = new AlphaType(inputUnion.size()); if (Verbose >= VERBOSE_ASSEMBLE_MESSAGES) { const std::string filename(imageInfoList.front()->getFileName()); const int layer(imageInfoList.front()->getImageIndex()); const int layers(imageInfoList.front()->numImages()); if (OneAtATime) { std::cerr << command << ": info: loading next image: " << filename << " " << layer + 1 << '/' << layers << std::endl; } else { std::cerr << command << ": info: combining non-overlapping images: " << filename << " " << layer + 1 << '/' << layers; std::cerr.flush(); } } const vigra::Diff2D imagePos = imageInfoList.front()->getPosition(); import(*imageInfoList.front(), vigra::destIter(image->upperLeft() + imagePos - inputUnion.upperLeft()), vigra::destIter(imageA->upperLeft() + imagePos - inputUnion.upperLeft())); imageInfoList.erase(imageInfoList.begin()); if (!OneAtATime) { // Attempt to assemble additional non-overlapping images. // List of ImageImportInfos we decide to assemble. std::list::iterator> toBeRemoved; std::list::iterator i; for (i = imageInfoList.begin(); i != imageInfoList.end(); i++) { vigra::ImageImportInfo* info = *i; // Load the next image. std::unique_ptr src {new ImageType(info->size())}; std::unique_ptr srcA {new AlphaType(info->size())}; import(*info, destImage(*src), destImage(*srcA)); // Check for overlap. bool overlapFound = false; AlphaIteratorType dy = imageA->upperLeft() - inputUnion.upperLeft() + info->getPosition(); AlphaAccessor da = imageA->accessor(); AlphaIteratorType sy = srcA->upperLeft(); AlphaIteratorType send = srcA->lowerRight(); AlphaAccessor sa = srcA->accessor(); for(; sy.y < send.y; ++sy.y, ++dy.y) { AlphaIteratorType sx = sy; AlphaIteratorType dx = dy; for(; sx.x < send.x; ++sx.x, ++dx.x) { if (sa(sx) && da(dx)) { overlapFound = true; break; } } if (overlapFound) { break; } } if (!overlapFound) { // Copy src and srcA into image and imageA. if (Verbose >= VERBOSE_ASSEMBLE_MESSAGES) { std::cerr << " " << info->getFileName(); std::cerr.flush(); } const vigra::Diff2D srcPos = info->getPosition(); #ifdef OPENMP omp::scoped_nested(true); omp::scoped_dynamic(true); #pragma omp parallel { #pragma omp single nowait { #endif vigra::omp::copyImageIf(srcImageRange(*src), maskImage(*srcA), vigra::destIter(image->upperLeft() - inputUnion.upperLeft() + srcPos)); vigra::omp::copyImageIf(srcImageRange(*srcA), maskImage(*srcA), vigra::destIter(imageA->upperLeft() - inputUnion.upperLeft() + srcPos)); #ifdef OPENMP } // omp single } // omp parallel #endif // Remove info from list later. toBeRemoved.push_back(i); } } // Erase the ImageImportInfos we used. for (std::list::iterator>::iterator r = toBeRemoved.begin(); r != toBeRemoved.end(); ++r) { imageInfoList.erase(*r); } } if (Verbose >= VERBOSE_ASSEMBLE_MESSAGES && !OneAtATime) { std::cerr << std::endl; } // Calculate bounding box of image. vigra::FindBoundingRectangle unionRect; vigra::inspectImageIf(srcIterRange(vigra::Diff2D(), vigra::Diff2D() + image->size()), srcImage(*imageA), unionRect); bb = unionRect(); if (Verbose >= VERBOSE_ABB_MESSAGES) { std::cerr << command << ": info: assembled images bounding box: " << unionRect() << std::endl; } return std::pair(image, imageA); } } // namespace enblend #endif /* __ASSEMBLE_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/mersenne.cc0000644000175000017500000000412512641706002014104 00000000000000/* * Copyright (C) 2015, 2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "openmp_def.h" #include "mersenne.h" MersenneTwister::MersenneTwister() : generator_(gsl_rng_alloc(gsl_rng_mt19937)) { assert(generator_); } MersenneTwister::MersenneTwister(const MersenneTwister& another_generator) : generator_(gsl_rng_clone(another_generator.generator_)) { assert(generator_); } MersenneTwister::~MersenneTwister() { gsl_rng_free(generator_); } MersenneTwister& MersenneTwister::operator=(const MersenneTwister& another_generator) { if (this != &another_generator) { gsl_rng_free(generator_); generator_ = gsl_rng_clone(another_generator.generator_); assert(generator_); } return *this; } void MersenneTwister::seed() { gsl_rng_set(generator_, gsl_rng_default_seed); } void MersenneTwister::seed(result_type a_seed) { gsl_rng_set(generator_, a_seed); } void UniformMersenneTwister::non_deterministic_seed() { #ifdef DEBUG seed(); // apply default seed in all threads for reproducibility #else unsigned seed_value = static_cast(1 + omp_get_thread_num()); // ANTICIPATED CHANGE: Tap into /dev/random. const clock_t now = clock(); if (now != static_cast(-1)) { seed_value ^= static_cast(now); } seed(seed_value); #endif } enblend-enfuse-4.2/src/rect2d.hxx0000644000175000017500000000141012641704341013673 00000000000000#ifndef RECT2D_HXX_ #define RECT2D_HXX_ #include #include namespace vigra_ext { template inline vigra::triple apply(const vigra::Rect2D& rectangle, const vigra::triple& image) { return vigra::make_triple(image.first + rectangle.upperLeft(), image.first + rectangle.lowerRight(), image.third); } template inline std::pair apply(const vigra::Rect2D& rectangle, const std::pair& image) { return std::make_pair(image.first + rectangle.upperLeft(), image.second); } } #endif // RECT2D_HXX_ enblend-enfuse-4.2/src/embrace0000755000175000017500000001426212314302567013315 00000000000000#! /usr/bin/env perl # This file is part of Enblend. # Licence details can be found in the file COPYING. # name: embrace # synopsis: convert text files to an assembler-, C-, or C++-string # author: Dr. Ch. L. Spiel # Perl version: 5.14.2 use strict; use warnings; use English; use File::Basename; use Getopt::Long; use IO::File; use constant COMMAND_NAME => basename $PROGRAM_NAME; my %param = (CHECKSUM => 0, # no checksum LABEL => 'kernel', # string name in target format FORMAT => 'c', # conversion format VERBOSE => 0); # default: quiet sub gnu_quote { return qq(\`@_'); } package Converter; use strict; use Carp qw(croak); use Digest::MD5; use English; sub new { my ($this, @arguments) = @_; my $class = ref $this || $this; my $self = {CHECKSUM => 0}; bless $self, $class; $self->_initialize(@arguments); return $self } sub _initialize { my ($self, $label) = @_; $self->{LABEL} = $label; } sub label { my $self = shift; return $self->{LABEL}; } sub during_open { my ($self, $filename, $function, @arguments) = @_; my $file = IO::File->new($filename, 'r') or die(main::COMMAND_NAME, ": error opening file ", main::gnu_quote($filename), ": $OS_ERROR\n"); while (defined(my $line = readline $file)) { chomp $line; $function->($self, $line, @arguments); } $file->close or die(main::COMMAND_NAME, ": error closing file ", main::gnu_quote($filename), ": $OS_ERROR\n"); } sub convert { my ($self, $filename) = @_; croak("does not understand `convert'") } sub add_checksum { my ($self, $toggle) = @_; $self->{CHECKSUM} = ($toggle != 0); } sub checksum { my $self = shift; return $self->{CHECKSUM}; } sub md5sum { my ($self, $filename) = @_; my $md5 = Digest::MD5->new; my $file = IO::File->new($filename, 'r'); my $md5sum = $md5->addfile($file); my $result = $md5sum->hexdigest; $file->close(); return $result; } package CXX_Converter; use strict; use base 'Converter'; sub decorate_line { my ($self, $line) = @_; $line =~ s#\"#\\"#g; print qq(\n "$line\\n"); } sub quote_source { my ($self, $filename) = @_; print "const std::string ", $self->label, "("; $self->during_open($filename, \&decorate_line); print ");\n"; } sub compute_md5 { my ($self, $filename) = @_; print "const std::string ", $self->label, qq{_md5("}, $self->md5sum($filename), qq{");\n}; } sub convert { my ($self, $filename) = @_; $self->quote_source($filename); $self->compute_md5($filename) if $self->checksum; } package C_Converter; use strict; use base 'Converter'; sub decorate_line { my ($self, $line) = @_; $line =~ s#\"#\\"#g; print qq(\n "$line\\n"); } sub quote_source { my ($self, $filename) = @_; print "const char ", $self->label, "[] ="; $self->during_open($filename, \&decorate_line); print ";\n"; } sub compute_md5 { my ($self, $filename) = @_; print "const char ", $self->label, qq(_md5[] = "), $self->md5sum($filename), qq(";\n); } sub convert { my ($self, $filename) = @_; $self->quote_source($filename); $self->compute_md5($filename) if $self->checksum; } package AS_Converter; use strict; use base 'Converter'; sub decorate_line { my ($self, $line) = @_; $line =~ s#\"#\\"#g; print qq( .ascii "$line\\n"\n); } sub quote_source { my ($self, $filename) = @_; my $label = $self->label; my $assembler_filename = $filename; $assembler_filename =~ s#\..*$#.s#; print <during_open($filename, \&decorate_line); print " .byte 0\n"; # make symbol an ASCIIZ string print "\n"; } sub compute_md5 { my ($self, $filename) = @_; my $label = $self->label . '_md5'; print <md5sum($filename), qq("\n); print " .byte 0\n"; # make symbol an ASCIIZ string print "\n"; } sub convert { my ($self, $filename) = @_; $self->quote_source($filename); $self->compute_md5($filename) if $self->checksum; print " .end\n"; } package main; use strict; use warnings; sub make_converter { my ($target_format, $label) = @_; my $format = lc $target_format; if ($format eq 'c') { return C_Converter->new($label); } elsif ($format eq 'c++') { return CXX_Converter->new($label); } elsif ($format eq 'as') { return AS_Converter->new($label); } else { die(COMMAND_NAME, ": unknown target format ", gnu_quote($target_format), "\n"); } } sub show_help { my @formats = qw(c c++ as); my $known_formats = join(', ', map {gnu_quote($_)} @formats); print < \$param{CHECKSUM}, 'h|help' => \&show_help, 'l|label=s' => \$param{LABEL}, 'f|format=s' => \$param{FORMAT}, 'v|verbose' => \$param{VERBOSE}) or die(COMMAND_NAME, ": failed parsing command line options\n"); my $converter = make_converter($param{FORMAT}, $param{LABEL}); $converter->add_checksum($param{CHECKSUM}); foreach my $source (@ARGV) { $converter->convert($source); } } main(); enblend-enfuse-4.2/src/pyramid.h0000644000175000017500000022156512641706002013610 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PYRAMID_H_INCLUDED_ #define PYRAMID_H_INCLUDED_ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include "fixmath.h" namespace enblend { template inline static t imul6(t a_value) {return 6 * a_value;} template inline static t imul5(t a_value) {return 5 * a_value;} template inline static t imul4(t a_value) {return 4 * a_value;} template inline static t imul11(t a_value) {return 11 * a_value;} template inline static t amul6(t an_alpha) {return 6 * an_alpha;} /** Calculate the half-width of a n-level filter. * Assumes that the input function is a left-handed function, * and the last non-zero input is at location 0. * Returns the location of the last non-zero output. */ inline unsigned int filterHalfWidth(const unsigned int levels) { vigra_precondition(levels >= 1 && levels <= MAX_PYRAMID_LEVELS, "filterHalfWidth: levels outside of permissible range"); // This is the arithmetic half width. return levels == 1 ? 0 : (1 << (levels + 1)) - 4; } //////////////////////////////////////////////////////////////////////////////////////////////// // // Burt & Adelson Reduce operation // //////////////////////////////////////////////////////////////////////////////////////////////// /** This version is for images with alpha channels. * Gaussian blur, downsampling, and extrapolation in one pass over * the input image using SKIPSM-based algorithm. * Uses only integer math, visits each pixel only once. * * Reference: * Frederick M. Waltz and John W.V. Miller. * An efficient algorithm for Gaussian blur using finite-state machines. * SPIE Conf. on Machine Vision Systems for Inspection and Metrology VII. November 1998. * * ************************************************************************************************* * 1-D explanation of algorithm: * * src image pixels: A B C D E F G * dst image pixels: W X Y Z * * Algorithm iterates over src image pixels from left to right. * At even src image pixels, the output of the previous dst image pixel is calculated. * For example, when visiting E, the value of X is written to the dst image. * * State variables before visiting E: * sr0 = C * sr1 = A + 4B * srp = 4D * * State variables after visiting E: * sr0 = E * sr1 = C + 4D * srp = 4D * X = A + 4B + 6C + 4D + E * * Updates when visiting even source pixel: * (all updates occur in parallel) * sr0 <= current * sr1 <= sr0 + srp * dst(-1) <= sr1 + 6*sr0 + srp + current * * Updates when visiting odd source pixel: * srp <= 4*current * * ************************************************************************************************* * 2-D explanation: * * src image pixels: A B C D E dst image pixels: a b c * F G H I J * K L M N O d e f * P Q R S T * U V W X Y g h i * * Algorithm visits all src image pixels from left to right and top to bottom. * When visiting src pixel Y, the value of e will be written to the dst image. * * State variables before visiting Y: * sr0 = W * sr1 = U + 4V * srp = 4X * sc0[2] = K + 4L + 6M + 4N + O * sc1[2] = (A + 4B + 6C + 4D + E) + 4*(F + 4G + 6H + 4I + J) * scp[2] = 4*(P + 4Q + 6R + 4S + T) * * State variables after visiting Y: * sr0 = Y * sr1 = W + 4X * srp = 4X * sc0[2] = U + 4V + 6W + 4X + Y * sc1[2] = (K + 4L + 6M + 4N + O) + 4*(P + 4Q + 6R + 4S + T) * scp[2] = 4*(P + 4Q + 6R + 4S + T) * e = 1 * (A + 4B + 6C + 4D + E) * + 4 * (F + 4G + 6H + 4I + J) * + 6 * (K + 4L + 6M + 4N + O) * + 4 * (P + 4Q + 6R + 4S + T) * + 1 * (U + 4V + 6W + 4X + Y) * * Updates when visiting (even x, even y) source pixel: * (all updates occur in parallel) * sr0 <= current * sr1 <= sr0 + srp * sc0[x] <= sr1 + 6*sr0 + srp + current * sc1[x] <= sc0[x] + scp[x] * dst(-1,-1) <= sc1[x] + 6*sc0[x] + scp + (new sc0[x]) * * Updates when visiting (odd x, even y) source pixel: * srp <= 4*current * * Updates when visiting (even x, odd y) source pixel: * sr0 <= current * sr1 <= sr0 + srp * scp[x] <= 4*(sr1 + 6*sr0 + srp + current) * * Updates when visting (odd x, odd y) source pixel: * srp <= 4*current */ template inline void reduce(bool wraparound, SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, AlphaIterator alpha_upperleft, AlphaAccessor aa, DestImageIterator dest_upperleft, DestImageIterator dest_lowerright, DestAccessor da, DestAlphaIterator dest_alpha_upperleft, DestAlphaIterator dest_alpha_lowerright, DestAlphaAccessor daa) { typedef typename DestAccessor::value_type DestPixelType; typedef typename DestAlphaAccessor::value_type DestAlphaPixelType; int src_w = src_lowerright.x - src_upperleft.x; int src_h = src_lowerright.y - src_upperleft.y; int dst_w = dest_lowerright.x - dest_upperleft.x; //int dst_h = dest_lowerright.y - dest_upperleft.y; vigra_precondition(src_w > 1 && src_h > 1, "src image too small in reduce"); // State variables for source image pixel values SKIPSMImagePixelType isr0, isr1, isrp; SKIPSMImagePixelType* isc0 = new SKIPSMImagePixelType[dst_w + 1]; SKIPSMImagePixelType* isc1 = new SKIPSMImagePixelType[dst_w + 1]; SKIPSMImagePixelType* iscp = new SKIPSMImagePixelType[dst_w + 1]; // State variables for source mask pixel values SKIPSMAlphaPixelType asr0, asr1, asrp; SKIPSMAlphaPixelType* asc0 = new SKIPSMAlphaPixelType[dst_w + 1]; SKIPSMAlphaPixelType* asc1 = new SKIPSMAlphaPixelType[dst_w + 1]; SKIPSMAlphaPixelType* ascp = new SKIPSMAlphaPixelType[dst_w + 1]; // Convenient constants const SKIPSMImagePixelType SKIPSMImageZero(vigra::NumericTraits::zero()); const SKIPSMAlphaPixelType SKIPSMAlphaZero(vigra::NumericTraits::zero()); const SKIPSMAlphaPixelType SKIPSMAlphaOne(vigra::NumericTraits::one()); const DestPixelType DestImageZero(vigra::NumericTraits::zero()); const DestAlphaPixelType DestAlphaZero(vigra::NumericTraits::zero()); const DestAlphaPixelType DestAlphaMax(vigra::NumericTraits::max()); DestImageIterator dy = dest_upperleft; DestImageIterator dx = dy; SrcImageIterator sy = src_upperleft; SrcImageIterator sx = sy; AlphaIterator ay = alpha_upperleft; AlphaIterator ax = ay; DestAlphaIterator day = dest_alpha_upperleft; DestAlphaIterator dax = day; bool evenY = true; bool evenX = true; int srcy = 0; int srcx = 0; //int dsty = 0; int dstx = 0; // First row { if (wraparound) { asr0 = aa(ay, vigra::Diff2D(src_w - 2, 0)) ? SKIPSMAlphaOne : SKIPSMAlphaZero; asr1 = SKIPSMAlphaZero; asrp = aa(ay, vigra::Diff2D(src_w - 1, 0)) ? (SKIPSMAlphaOne * 4) : SKIPSMAlphaZero; isr0 = aa(ay, vigra::Diff2D(src_w - 2, 0)) ? SKIPSMImagePixelType(sa(sy, vigra::Diff2D(src_w - 2, 0))) : SKIPSMImageZero; isr1 = SKIPSMImageZero; isrp = aa(ay, vigra::Diff2D(src_w - 1, 0)) ? vigra::NumericTraits::fromRealPromote(SKIPSMImagePixelType(sa(sy, vigra::Diff2D(src_w - 1, 0))) * 4) : SKIPSMImageZero; } else { asr0 = SKIPSMAlphaZero; asr1 = SKIPSMAlphaZero; asrp = SKIPSMAlphaZero; isr0 = SKIPSMImageZero; isr1 = SKIPSMImageZero; isrp = SKIPSMImageZero; } for (sx = sy, ax = ay, evenX = true, srcx = 0, dstx = 0; srcx < src_w; ++srcx, ++sx.x, ++ax.x) { SKIPSMAlphaPixelType mcurrent(aa(ax) ? SKIPSMAlphaOne : SKIPSMAlphaZero); SKIPSMImagePixelType icurrent(aa(ax) ? SKIPSMImagePixelType(sa(sx)) : SKIPSMImageZero); if (evenX) { asc1[dstx] = SKIPSMAlphaZero; asc0[dstx] = asr1 + amul6(asr0) + asrp + mcurrent; asr1 = asr0 + asrp; asr0 = mcurrent; isc1[dstx] = SKIPSMImageZero; isc0[dstx] = isr1 + imul6(isr0) + isrp + icurrent; isr1 = isr0 + isrp; isr0 = icurrent; } else { asrp = mcurrent * 4; isrp = icurrent * 4; ++dstx; } evenX = !evenX; } // Last entries in first row if (!evenX) { // previous srcx was even ++dstx; if (wraparound) { asc1[dstx] = SKIPSMAlphaZero; asc0[dstx] = asr1 + amul6(asr0) + (aa(ay) ? (SKIPSMAlphaOne * 4) : SKIPSMAlphaZero) + (aa(ay, vigra::Diff2D(1,0)) ? SKIPSMAlphaOne : SKIPSMAlphaZero); isc1[dstx] = SKIPSMImageZero; isc0[dstx] = isr1 + imul6(isr0) + (aa(ay) ? vigra::NumericTraits::fromRealPromote(SKIPSMImagePixelType(sa(sy)) * 4) : SKIPSMImageZero) + (aa(ay, vigra::Diff2D(1, 0)) ? vigra::NumericTraits::fromRealPromote(SKIPSMImagePixelType(sa(sy, vigra::Diff2D(1, 0)))) : SKIPSMImageZero); } else { asc1[dstx] = SKIPSMAlphaZero; asc0[dstx] = asr1 + amul6(asr0); isc1[dstx] = SKIPSMImageZero; isc0[dstx] = isr1 + imul6(isr0); } } else { // previous srcx was odd if (wraparound) { asc1[dstx] = SKIPSMAlphaZero; asc0[dstx] = asr1 + amul6(asr0) + asrp + (aa(ay) ? SKIPSMAlphaOne : SKIPSMAlphaZero); isc1[dstx] = SKIPSMImageZero; isc0[dstx] = isr1 + imul6(isr0) + isrp + (aa(ay) ? SKIPSMImagePixelType(sa(sy)) : SKIPSMImageZero); } else { asc1[dstx] = SKIPSMAlphaZero; asc0[dstx] = asr1 + amul6(asr0) + asrp; isc1[dstx] = SKIPSMImageZero; isc0[dstx] = isr1 + imul6(isr0) + isrp; } } } ++sy.y; ++ay.y; // Main Rows { for (evenY = false, srcy = 1; srcy < src_h; ++srcy, ++sy.y, ++ay.y) { if (wraparound) { asr0 = aa(ay, vigra::Diff2D(src_w - 2, 0)) ? SKIPSMAlphaOne : SKIPSMAlphaZero; asr1 = SKIPSMAlphaZero; asrp = aa(ay, vigra::Diff2D(src_w - 1, 0)) ? (SKIPSMAlphaOne * 4) : SKIPSMAlphaZero; isr0 = aa(ay, vigra::Diff2D(src_w - 2, 0)) ? SKIPSMImagePixelType(sa(sy, vigra::Diff2D(src_w - 2,0))) : SKIPSMImageZero; isr1 = SKIPSMImageZero; isrp = aa(ay, vigra::Diff2D(src_w - 1, 0)) ? vigra::NumericTraits::fromRealPromote(SKIPSMImagePixelType(sa(sy, vigra::Diff2D(src_w - 1,0))) * 4) : SKIPSMImageZero; } else { asr0 = SKIPSMAlphaZero; asr1 = SKIPSMAlphaZero; asrp = SKIPSMAlphaZero; isr0 = SKIPSMImageZero; isr1 = SKIPSMImageZero; isrp = SKIPSMImageZero; } if (evenY) { // Even-numbered row // First entry in row sx = sy; ax = ay; if (wraparound) { asr1 = asr0 + asrp; isr1 = isr0 + isrp; } asr0 = aa(ax) ? SKIPSMAlphaOne : SKIPSMAlphaZero; isr0 = aa(ax) ? SKIPSMImagePixelType(sa(sx)) : SKIPSMImageZero; // isc*[0] are never used ++sx.x; ++ax.x; dx = dy; dax = day; // Main entries in row for (evenX = false, srcx = 1, dstx = 0; srcx < src_w; ++srcx, ++sx.x, ++ax.x) { SKIPSMAlphaPixelType mcurrent(aa(ax) ? SKIPSMAlphaOne : SKIPSMAlphaZero); SKIPSMImagePixelType icurrent(aa(ax) ? SKIPSMImagePixelType(sa(sx)) : SKIPSMImageZero); if (evenX) { SKIPSMAlphaPixelType ap = asc1[dstx] + amul6(asc0[dstx]) + ascp[dstx]; asc1[dstx] = asc0[dstx] + ascp[dstx]; asc0[dstx] = asr1 + amul6(asr0) + asrp + mcurrent; asr1 = asr0 + asrp; asr0 = mcurrent; ap += asc0[dstx]; SKIPSMImagePixelType ip = isc1[dstx] + imul6(isc0[dstx]) + iscp[dstx]; isc1[dstx] = isc0[dstx] + iscp[dstx]; isc0[dstx] = isr1 + imul6(isr0) + isrp + icurrent; isr1 = isr0 + isrp; isr0 = icurrent; if (ap) { ip += isc0[dstx]; // OVERFLOW!!! ip /= SKIPSMImagePixelType(ap); da.set(DestPixelType(ip), dx); daa.set(DestAlphaMax, dax); } else { da.set(DestImageZero, dx); daa.set(DestAlphaZero, dax); } ++dx.x; ++dax.x; } else { asrp = mcurrent * 4; isrp = icurrent * 4; ++dstx; } evenX = !evenX; } // Last entries in row if (!evenX) { // previous srcx was even ++dstx; SKIPSMAlphaPixelType ap = asc1[dstx] + amul6(asc0[dstx]) + ascp[dstx]; asc1[dstx] = asc0[dstx] + ascp[dstx]; if (wraparound) { asc0[dstx] = asr1 + amul6(asr0) + (aa(ay) ? (SKIPSMAlphaOne * 4) : SKIPSMAlphaZero) + (aa(ay, vigra::Diff2D(1,0)) ? SKIPSMAlphaOne : SKIPSMAlphaZero); } else { asc0[dstx] = asr1 + amul6(asr0); } ap += asc0[dstx]; SKIPSMImagePixelType ip = isc1[dstx] + imul6(isc0[dstx]) + iscp[dstx]; isc1[dstx] = isc0[dstx] + iscp[dstx]; if (wraparound) { isc0[dstx] = isr1 + imul6(isr0) + (aa(ay) ? vigra::NumericTraits::fromRealPromote(SKIPSMImagePixelType(sa(sy)) * 4) : SKIPSMImageZero) + (aa(ay, vigra::Diff2D(1, 0)) ? SKIPSMImagePixelType(sa(sy, vigra::Diff2D(1, 0))) : SKIPSMImageZero); } else { isc0[dstx] = isr1 + imul6(isr0); } if (ap) { ip += isc0[dstx]; ip /= SKIPSMImagePixelType(ap); da.set(DestPixelType(ip), dx); daa.set(DestAlphaMax, dax); } else { da.set(DestImageZero, dx); daa.set(DestAlphaZero, dax); } } else { // Previous srcx was odd SKIPSMAlphaPixelType ap = asc1[dstx] + amul6(asc0[dstx]) + ascp[dstx]; asc1[dstx] = asc0[dstx] + ascp[dstx]; if (wraparound) { asc0[dstx] = asr1 + amul6(asr0) + asrp + (aa(ay) ? SKIPSMAlphaOne : SKIPSMAlphaZero); } else { asc0[dstx] = asr1 + amul6(asr0) + asrp; } ap += asc0[dstx]; SKIPSMImagePixelType ip = isc1[dstx] + imul6(isc0[dstx]) + iscp[dstx]; isc1[dstx] = isc0[dstx] + iscp[dstx]; if (wraparound) { isc0[dstx] = isr1 + imul6(isr0) + isrp + (aa(ay) ? SKIPSMImagePixelType(sa(sy)) : SKIPSMImageZero); } else { isc0[dstx] = isr1 + imul6(isr0) + isrp; } if (ap) { ip += isc0[dstx]; ip /= SKIPSMImagePixelType(ap); da.set(DestPixelType(ip), dx); daa.set(DestAlphaMax, dax); } else { da.set(DestImageZero, dx); daa.set(DestAlphaZero, dax); } } ++dy.y; ++day.y; } else { // First entry in odd-numbered row sx = sy; ax = ay; if (wraparound) { asr1 = asr0 + asrp; isr1 = isr0 + isrp; } asr0 = aa(ax) ? SKIPSMAlphaOne : SKIPSMAlphaZero; isr0 = aa(ax) ? SKIPSMImagePixelType(sa(sx)) : SKIPSMImageZero; // isc*[0] are never used ++sx.x; ++ax.x; // Main entries in odd-numbered row for (evenX = false, srcx = 1, dstx = 0; srcx < src_w; ++srcx, ++sx.x, ++ax.x) { SKIPSMAlphaPixelType mcurrent(aa(ax) ? SKIPSMAlphaOne : SKIPSMAlphaZero); SKIPSMImagePixelType icurrent(aa(ax) ? SKIPSMImagePixelType(sa(sx)) : SKIPSMImageZero); if (evenX) { ascp[dstx] = (asr1 + amul6(asr0) + asrp + mcurrent) * 4; asr1 = asr0 + asrp; asr0 = mcurrent; iscp[dstx] = (isr1 + imul6(isr0) + isrp + icurrent) * 4; isr1 = isr0 + isrp; isr0 = icurrent; } else { asrp = mcurrent * 4; isrp = icurrent * 4; ++dstx; } evenX = !evenX; } // Last entries in row if (!evenX) { // previous srcx was even ++dstx; if (wraparound) { ascp[dstx] = (asr1 + amul6(asr0) + (aa(ay) ? (SKIPSMAlphaOne * 4) : SKIPSMAlphaZero) + (aa(ay, vigra::Diff2D(1,0)) ? SKIPSMAlphaOne : SKIPSMAlphaZero)) * 4; iscp[dstx] = (isr1 + imul6(isr0) + (aa(ay) ? vigra::NumericTraits::fromRealPromote(SKIPSMImagePixelType(sa(sy)) * 4) : SKIPSMImageZero) + (aa(ay, vigra::Diff2D(1, 0)) ? SKIPSMImagePixelType(sa(sy, vigra::Diff2D(1, 0))) : SKIPSMImageZero)) * 4; } else { ascp[dstx] = (asr1 + amul6(asr0)) * 4; iscp[dstx] = (isr1 + imul6(isr0)) * 4; } } else { // previous srcx was odd if (wraparound) { ascp[dstx] = (asr1 + amul6(asr0) + asrp + (aa(ay) ? SKIPSMAlphaOne : SKIPSMAlphaZero)) * 4; iscp[dstx] = (isr1 + imul6(isr0) + isrp + (aa(ay) ? SKIPSMImagePixelType(sa(sy)) : SKIPSMImageZero)) * 4; } else { ascp[dstx] = (asr1 + amul6(asr0) + asrp) * 4; iscp[dstx] = (isr1 + imul6(isr0) + isrp) * 4; } } } evenY = !evenY; } } // Last Rows { if (!evenY) { // Last srcy was even // odd row will set all iscp[] to zero // even row will do: //isc0[dstx] = 0; //isc1[dstx] = isc0[dstx] + 4*iscp[dstx] //out = isc1[dstx] + 6*isc0[dstx] + 4*iscp[dstx] + newisc0[dstx] for (dstx = 1, dx = dy, dax = day; dstx < dst_w + 1; ++dstx, ++dx.x, ++dax.x) { SKIPSMAlphaPixelType ap = asc1[dstx] + amul6(asc0[dstx]); if (ap) { SKIPSMImagePixelType ip = (isc1[dstx] + imul6(isc0[dstx])) / SKIPSMImagePixelType(ap); da.set(DestPixelType(ip), dx); daa.set(DestAlphaMax, dax); } else { da.set(DestImageZero, dx); daa.set(DestAlphaZero, dax); } } } else { // Last srcy was odd // even row will do: // isc0[dstx] = 0; // isc1[dstx] = isc0[dstx] + 4*iscp[dstx] // out = isc1[dstx] + 6*isc0[dstx] + 4*iscp[dstx] + newisc0[dstx] for (dstx = 1, dx = dy, dax = day; dstx < dst_w + 1; ++dstx, ++dx.x, ++dax.x) { SKIPSMAlphaPixelType ap = asc1[dstx] + amul6(asc0[dstx]) + ascp[dstx]; if (ap) { SKIPSMImagePixelType ip = (isc1[dstx] + imul6(isc0[dstx]) + iscp[dstx]) / SKIPSMImagePixelType(ap); da.set(DestPixelType(ip), dx); daa.set(DestAlphaMax, dax); } else { da.set(DestImageZero, dx); daa.set(DestAlphaZero, dax); } } } } delete [] isc0; delete [] isc1; delete [] iscp; delete [] asc0; delete [] asc1; delete [] ascp; } // Version using argument object factories. template inline void reduce(bool wraparound, vigra::triple src, vigra::pair mask, vigra::triple dest, vigra::triple destMask) { reduce(wraparound, src.first, src.second, src.third, mask.first, mask.second, dest.first, dest.second, dest.third, destMask.first, destMask.second, destMask.third); }; /** The Burt & Adelson Reduce operation. * This version is for images that do not have alpha channels. */ template inline void reduce(bool wraparound, SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, DestImageIterator dest_upperleft, DestImageIterator dest_lowerright, DestAccessor da) { typedef typename DestAccessor::value_type DestPixelType; const int src_w = src_lowerright.x - src_upperleft.x; const int src_h = src_lowerright.y - src_upperleft.y; const int dst_w = dest_lowerright.x - dest_upperleft.x; //const int dst_h = dest_lowerright.y - dest_upperleft.y; vigra_precondition(src_w > 1 && src_h > 1, "src image too small in reduce"); // State variables for source image pixel values SKIPSMImagePixelType isr0, isr1, isrp; SKIPSMImagePixelType* isc0 = new SKIPSMImagePixelType[dst_w + 1]; SKIPSMImagePixelType* isc1 = new SKIPSMImagePixelType[dst_w + 1]; SKIPSMImagePixelType* iscp = new SKIPSMImagePixelType[dst_w + 1]; // Convenient constants const SKIPSMImagePixelType SKIPSMImageZero(vigra::NumericTraits::zero()); DestImageIterator dy = dest_upperleft; DestImageIterator dx = dy; SrcImageIterator sy = src_upperleft; SrcImageIterator sx = sy; bool evenY = true; bool evenX = true; int srcy = 0; int srcx = 0; //int dsty = 0; int dstx = 0; // First row { if (wraparound) { isr0 = SKIPSMImagePixelType(sa(sy, vigra::Diff2D(src_w - 2, 0))); isr1 = SKIPSMImageZero; isrp = SKIPSMImagePixelType(sa(sy, vigra::Diff2D(src_w - 1, 0))) * 4; } else { isr0 = SKIPSMImagePixelType(sa(sy)); isr1 = SKIPSMImageZero; isrp = SKIPSMImagePixelType(sa(sy)) * 4; } // Main pixels in first row for (sx = sy, evenX = true, srcx = 0, dstx = 0; srcx < src_w; ++srcx, ++sx.x) { SKIPSMImagePixelType icurrent(SKIPSMImagePixelType(sa(sx))); if (evenX) { isc0[dstx] = isr1 + imul6(isr0) + isrp + icurrent; isc1[dstx] = imul5(isc0[dstx]); isr1 = isr0 + isrp; isr0 = icurrent; } else { isrp = icurrent * 4; ++dstx; } evenX = !evenX; } // Last entries in first row if (!evenX) { // previous srcx was even ++dstx; if (wraparound) { isc0[dstx] = isr1 + imul6(isr0) + (SKIPSMImagePixelType(sa(sy)) * 4) + SKIPSMImagePixelType(sa(sy, vigra::Diff2D(1, 0))); isc1[dstx] = imul5(isc0[dstx]); } else { isc0[dstx] = isr1 + imul11(isr0); isc1[dstx] = imul5(isc0[dstx]); } } else { // previous srcx was odd if (wraparound) { isc0[dstx] = isr1 + imul6(isr0) + isrp + SKIPSMImagePixelType(sa(sy)); isc1[dstx] = imul5(isc0[dstx]); } else { isc0[dstx] = isr1 + imul6(isr0) + isrp + (isrp / 4); isc1[dstx] = imul5(isc0[dstx]); } } } ++sy.y; // Main Rows { for (evenY = false, srcy = 1; srcy < src_h; ++srcy, ++sy.y) { if (wraparound) { isr0 = SKIPSMImagePixelType(sa(sy, vigra::Diff2D(src_w - 2, 0))); isr1 = SKIPSMImageZero; isrp = SKIPSMImagePixelType(sa(sy, vigra::Diff2D(src_w - 1, 0))) * 4; } else { isr0 = SKIPSMImagePixelType(sa(sy)); isr1 = SKIPSMImageZero; isrp = SKIPSMImagePixelType(sa(sy)) * 4; } if (evenY) { // Even-numbered row // First entry in row sx = sy; isr1 = isr0 + isrp; isr0 = SKIPSMImagePixelType(sa(sx)); // isc*[0] are never used ++sx.x; dx = dy; // Main entries in row for (evenX = false, srcx = 1, dstx = 0; srcx < src_w; ++srcx, ++sx.x) { SKIPSMImagePixelType icurrent(SKIPSMImagePixelType(sa(sx))); if (evenX) { SKIPSMImagePixelType ip = isc1[dstx] + imul6(isc0[dstx]) + iscp[dstx]; isc1[dstx] = isc0[dstx] + iscp[dstx]; isc0[dstx] = isr1 + imul6(isr0) + isrp + icurrent; isr1 = isr0 + isrp; isr0 = icurrent; ip += isc0[dstx]; ip /= 256; da.set(DestPixelType(ip), dx); ++dx.x; } else { isrp = icurrent * 4; ++dstx; } evenX = !evenX; } // Last entries in row if (!evenX) { // previous srcx was even ++dstx; SKIPSMImagePixelType ip = isc1[dstx] + imul6(isc0[dstx]) + iscp[dstx]; isc1[dstx] = isc0[dstx] + iscp[dstx]; if (wraparound) { isc0[dstx] = isr1 + imul6(isr0) + (SKIPSMImagePixelType(sa(sy)) * 4) + SKIPSMImagePixelType(sa(sy, vigra::Diff2D(1, 0))); } else { isc0[dstx] = isr1 + imul11(isr0); } ip += isc0[dstx]; ip /= 256; da.set(DestPixelType(ip), dx); } else { // Previous srcx was odd SKIPSMImagePixelType ip = isc1[dstx] + imul6(isc0[dstx]) + iscp[dstx]; isc1[dstx] = isc0[dstx] + iscp[dstx]; if (wraparound) { isc0[dstx] = isr1 + imul6(isr0) + isrp + SKIPSMImagePixelType(sa(sy)); } else { isc0[dstx] = isr1 + imul6(isr0) + isrp + (isrp / 4); } ip += isc0[dstx]; ip /= 256; da.set(DestPixelType(ip), dx); } ++dy.y; } else { // First entry in odd-numbered row sx = sy; isr1 = isr0 + isrp; isr0 = SKIPSMImagePixelType(sa(sx)); // isc*[0] are never used ++sx.x; // Main entries in odd-numbered row for (evenX = false, srcx = 1, dstx = 0; srcx < src_w; ++srcx, ++sx.x) { SKIPSMImagePixelType icurrent(SKIPSMImagePixelType(sa(sx))); if (evenX) { iscp[dstx] = (isr1 + imul6(isr0) + isrp + icurrent) * 4; isr1 = isr0 + isrp; isr0 = icurrent; } else { isrp = icurrent * 4; ++dstx; } evenX = !evenX; } // Last entries in row if (!evenX) { // previous srcx was even ++dstx; if (wraparound) { iscp[dstx] = (isr1 + imul6(isr0) + (SKIPSMImagePixelType(sa(sy)) * 4) + SKIPSMImagePixelType(sa(sy, vigra::Diff2D(1, 0))) ) * 4; } else { iscp[dstx] = (isr1 + imul11(isr0)) * 4; } } else { // previous srcx was odd if (wraparound) { iscp[dstx] = (isr1 + imul6(isr0) + isrp + SKIPSMImagePixelType(sa(sy))) * 4; } else { iscp[dstx] = (isr1 + imul6(isr0) + isrp + (isrp / 4)) * 4; } } } evenY = !evenY; } } // Last Rows { if (!evenY) { // Last srcy was even // odd row will set all iscp[] to zero // even row will do: //isc0[dstx] = 0; //isc1[dstx] = isc0[dstx] + 4*iscp[dstx] //out = isc1[dstx] + 6*isc0[dstx] + 4*iscp[dstx] + newisc0[dstx] for (dstx = 1, dx = dy; dstx < dst_w + 1; ++dstx, ++dx.x) { SKIPSMImagePixelType ip = (isc1[dstx] + imul11(isc0[dstx])) / 256; da.set(DestPixelType(ip), dx); } } else { // Last srcy was odd // even row will do: // isc0[dstx] = 0; // isc1[dstx] = isc0[dstx] + 4*iscp[dstx] // out = isc1[dstx] + 6*isc0[dstx] + 4*iscp[dstx] + newisc0[dstx] for (dstx = 1, dx = dy; dstx < dst_w + 1; ++dstx, ++dx.x) { SKIPSMImagePixelType ip = (isc1[dstx] + imul6(isc0[dstx]) + iscp[dstx] + (iscp[dstx] / 4)) / 256; da.set(DestPixelType(ip), dx); } } } delete [] isc0; delete [] isc1; delete [] iscp; } // Version using argument object factories. template inline static void reduce(bool wraparound, vigra::triple src, vigra::triple dest) { reduce(wraparound, src.first, src.second, src.third, dest.first, dest.second, dest.third); } //////////////////////////////////////////////////////////////////////////////////////////////// // // Burt & Adelson Expand operation // //////////////////////////////////////////////////////////////////////////////////////////////// // SKIPSM update routine used when visiting a pixel in the top two rows // and the left two rows. #define SKIPSM_EXPAND(SCALE_OUT00, SCALE_OUT10, SCALE_OUT01, SCALE_OUT11) \ do { \ current = SKIPSMImagePixelType(sa(sx)); \ out00 = sc1a[srcx] + imul6(sc0a[srcx]); \ out10 = sc1b[srcx] + imul6(sc0b[srcx]); \ out01 = sc0a[srcx]; \ out11 = sc0b[srcx]; \ sc1a[srcx] = sc0a[srcx]; \ sc1b[srcx] = sc0b[srcx]; \ sc0a[srcx] = sr1 + imul6(sr0) + current; \ sc0b[srcx] = (sr0 + current) * 4; \ sr1 = sr0; \ sr0 = current; \ out00 += sc0a[srcx]; \ out10 += sc0b[srcx]; \ out01 += sc0a[srcx]; \ out11 += sc0b[srcx]; \ out00 /= SKIPSMImagePixelType(SCALE_OUT00); \ out10 /= SKIPSMImagePixelType(SCALE_OUT10); \ out01 /= SKIPSMImagePixelType(SCALE_OUT01); \ out11 /= SKIPSMImagePixelType(SCALE_OUT11); \ da.set(cf(SKIPSMImagePixelType(da(dx)), out00), dx); \ ++dx.x; \ da.set(cf(SKIPSMImagePixelType(da(dx)), out10), dx); \ ++dx.x; \ da.set(cf(SKIPSMImagePixelType(da(dxx)), out01), dxx); \ ++dxx.x; \ da.set(cf(SKIPSMImagePixelType(da(dxx)), out11), dxx); \ ++dxx.x; \ } while (false) // SKIPSM update routine used for the extra row under the main image body. #define SKIPSM_EXPAND_ROW_END(SCALE_OUT00, SCALE_OUT10, SCALE_OUT01, SCALE_OUT11) \ do { \ out00 = sc1a[srcx] + imul6(sc0a[srcx]); \ out10 = sc1b[srcx] + imul6(sc0b[srcx]); \ out00 /= SKIPSMImagePixelType(SCALE_OUT00); \ out10 /= SKIPSMImagePixelType(SCALE_OUT10); \ da.set(cf(da(dx), out00), dx); \ ++dx.x; \ da.set(cf(da(dx), out10), dx); \ ++dx.x; \ if (dst_h_even) { \ out01 = sc0a[srcx]; \ out11 = sc0b[srcx]; \ out01 /= SKIPSMImagePixelType(SCALE_OUT01); \ out11 /= SKIPSMImagePixelType(SCALE_OUT11); \ da.set(cf(da(dxx), out01), dxx); \ ++dxx.x; \ da.set(cf(da(dxx), out11), dxx); \ ++dxx.x; \ } \ } while (false) // SKIPSM update routine used for the extra column to the right // of the main image body. #define SKIPSM_EXPAND_COLUMN_END(SCALE_OUT00, SCALE_OUT10, SCALE_OUT01, SCALE_OUT11) \ do { \ out00 = sc1a[srcx] + imul6(sc0a[srcx]); \ out01 = sc0a[srcx]; \ out10 = sc1b[srcx] + imul6(sc0b[srcx]); \ out11 = sc0b[srcx]; \ sc1a[srcx] = sc0a[srcx]; \ sc1b[srcx] = sc0b[srcx]; \ sc0a[srcx] = sr1 + imul6(sr0); \ sc0b[srcx] = sr0 * 4; \ out00 += sc0a[srcx]; \ out01 += sc0a[srcx]; \ out00 /= SKIPSMImagePixelType(SCALE_OUT00); \ out01 /= SKIPSMImagePixelType(SCALE_OUT01); \ da.set(cf(da(dx), out00), dx); \ da.set(cf(da(dxx), out01), dxx); \ if (dst_w_even) { \ ++dx.x; \ ++dxx.x; \ out10 += sc0b[srcx]; \ out11 += sc0b[srcx]; \ out10 /= SKIPSMImagePixelType(SCALE_OUT10); \ out11 /= SKIPSMImagePixelType(SCALE_OUT11); \ da.set(cf(da(dx), out10), dx); \ da.set(cf(da(dxx), out11), dxx); \ } \ } while (false) // SKIPSM update routine used for the extra column to the right // of the main image body, with wraparound boundary conditions. // This version is for the case where the dst image has even width. #define SKIPSM_EXPAND_COLUMN_END_WRAPAROUND_EVEN(SCALE_OUT00, SCALE_OUT10, SCALE_OUT01, SCALE_OUT11) \ do { \ out00 = sc1a[srcx] + imul6(sc0a[srcx]); \ out01 = sc0a[srcx]; \ out10 = sc1b[srcx] + imul6(sc0b[srcx]); \ out11 = sc0b[srcx]; \ sc1a[srcx] = sc0a[srcx]; \ sc1b[srcx] = sc0b[srcx]; \ sc0a[srcx] = sr1 + imul6(sr0) + SKIPSMImagePixelType(sa(sy)); \ sc0b[srcx] = (sr0 + SKIPSMImagePixelType(sa(sy))) * 4; \ out00 += sc0a[srcx]; \ out01 += sc0a[srcx]; \ out00 /= SKIPSMImagePixelType(SCALE_OUT00); \ out01 /= SKIPSMImagePixelType(SCALE_OUT01); \ da.set(cf(da(dx), out00), dx); \ da.set(cf(da(dxx), out01), dxx); \ ++dx.x; \ ++dxx.x; \ out10 += sc0b[srcx]; \ out11 += sc0b[srcx]; \ out10 /= SKIPSMImagePixelType(SCALE_OUT10); \ out11 /= SKIPSMImagePixelType(SCALE_OUT11); \ da.set(cf(da(dx), out10), dx); \ da.set(cf(da(dxx), out11), dxx); \ } while (false) // SKIPSM update routine used for the extra column to the right // of the main image body, with wraparound boundary conditions. // This version is for the case where the dst image has odd width. #define SKIPSM_EXPAND_COLUMN_END_WRAPAROUND_ODD(SCALE_OUT00, SCALE_OUT01) \ do { \ out00 = sc1a[srcx] + imul6(sc0a[srcx]); \ out01 = sc0a[srcx]; \ out10 = sc1b[srcx] + imul6(sc0b[srcx]); \ out11 = sc0b[srcx]; \ sc1a[srcx] = sc0a[srcx]; \ sc1b[srcx] = sc0b[srcx]; \ sc0a[srcx] = sr1 + imul6(sr0) + imul4(SKIPSMImagePixelType(sa(sy))); \ sc0b[srcx] = (sr0 + SKIPSMImagePixelType(sa(sy))) * 4; \ out00 += sc0a[srcx]; \ out01 += sc0a[srcx]; \ out00 /= SKIPSMImagePixelType(SCALE_OUT00); \ out01 /= SKIPSMImagePixelType(SCALE_OUT01); \ da.set(cf(da(dx), out00), dx); \ da.set(cf(da(dxx), out01), dxx); \ } while (false) // SKIPSM update routine for the extra column to the right // of the extra row under the main image body. #define SKIPSM_EXPAND_ROW_COLUMN_END(SCALE_OUT00, SCALE_OUT10, SCALE_OUT01, SCALE_OUT11) \ do { \ out00 = sc1a[srcx] + imul6(sc0a[srcx]); \ out00 /= SKIPSMImagePixelType(SCALE_OUT00); \ da.set(cf(da(dx), out00), dx); \ if (dst_w_even) { \ out10 = sc1b[srcx] + imul6(sc0b[srcx]); \ out10 /= SKIPSMImagePixelType(SCALE_OUT10); \ ++dx.x; \ da.set(cf(da(dx), out10), dx); \ } \ if (dst_h_even) { \ out01 = sc0a[srcx]; \ out01 /= SKIPSMImagePixelType(SCALE_OUT01); \ da.set(cf(da(dxx), out01), dxx); \ if (dst_w_even) { \ out11 = sc0b[srcx]; \ out11 /= SKIPSMImagePixelType(SCALE_OUT11); \ ++dxx.x; \ da.set(cf(da(dxx), out11), dxx); \ } \ } \ } while (false) /** The Burt & Adelson Expand operation. * * Upsampling with Gaussian interpolation in one pass over the input image using SKIPSM-based algorithm. * Uses only integer math, visits each pixel only once. * * Explanation of algorithm: * * src image pixels: a b c dst image pixels: A B C D E * F G H I J * d e f K L M N O * P Q R S T * g h i U V W X Y * * Algorithm visits all src image pixels from left to right and top to bottom. * At each src pixel, four dst pixels are calculated. * When visiting src pixel i, dst pixels M, N, R and S are written. * * State variables before visiting i: * sr0 = h * sr1 = g * sc0a[2] = d + 6e + f * sc0b[2] = 4e + 4f * sc1a[2] = a + 6b + c * sc1b[2] = 4b + 4c * * State variables after visiting i: * sr0 = i * sr1 = h * sc0a[2] = g + 6h + i * sc0b[2] = 4h + 4i * sc1a[2] = d + 6e + f * sc1b[2] = 4e + 4f * * M = 1 * (a + 6b + c) * + 6 * (d + 6e + f) * + 1 * (g + 6h + i) * * N = 1 * (4b + 4c) * + 6 * (4e + 4f) * + 1 * (4h + 4i) * * R = 4 * (d + 6e + f) * + 4 * (g + 6h + i) * * S = 4 * (4e + 4f) * + 4 * (4h + 4i) * * Updates when visiting each src image pixel: * (all assignments occur in parallel) * sr0 <= current * sr1 <= sr0 * sc0a[x] <= sr1 + 6*sr0 + current * sc0b[x] <= 4*sr0 + 4*current * sc1a[x] <= sc0a[x] * sc1b[x] <= sc0b[x] * out(-2, -2) <= sc1a[x] + 6*sc0a[x] + (new sc0a[x]) * out(-1, -2) <= sc1b[x] + 6*sc0b[x] + (new sc0b[x]) * out(-2, -1) <= 4*sc0a[x] + 4*(new sc0a[x]) * out(-1, -1) <= 4*sc0b[x] + 4*(new sc0b[x]) * */ template void expand(bool add, bool wraparound, SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, DestImageIterator dest_upperleft, DestImageIterator dest_lowerright, DestAccessor da, CombineFunctor cf) { int src_w = src_lowerright.x - src_upperleft.x; int src_h = src_lowerright.y - src_upperleft.y; int dst_w = dest_lowerright.x - dest_upperleft.x; int dst_h = dest_lowerright.y - dest_upperleft.y; const bool dst_w_even = (dst_w & 1) == 0; const bool dst_h_even = (dst_h & 1) == 0; // SKIPSM state variables SKIPSMImagePixelType current; SKIPSMImagePixelType out00, out10, out01, out11; SKIPSMImagePixelType sr0, sr1; SKIPSMImagePixelType* sc0a = new SKIPSMImagePixelType[src_w + 1]; SKIPSMImagePixelType* sc0b = new SKIPSMImagePixelType[src_w + 1]; SKIPSMImagePixelType* sc1a = new SKIPSMImagePixelType[src_w + 1]; SKIPSMImagePixelType* sc1b = new SKIPSMImagePixelType[src_w + 1]; // Convenient constants const SKIPSMImagePixelType SKIPSMImageZero(vigra::NumericTraits::zero()); DestImageIterator dy = dest_upperleft; DestImageIterator dyy = dest_upperleft; DestImageIterator dx = dy; DestImageIterator dxx = dyy; SrcImageIterator sy = src_upperleft; SrcImageIterator sx = sy; int srcy = 0; int srcx = 0; //int dsty = 0; //int dstx = 0; // First row { // First column srcx = 0; sx = sy; sr0 = SKIPSMImagePixelType(sa(sx)); if (wraparound) { sr1 = SKIPSMImagePixelType(sa(sy, vigra::Diff2D(src_w - 1, 0))); if (!dst_w_even) { sr1 = imul4(sr1); } } else { sr1 = SKIPSMImageZero; } // sc*[0] are irrelevant srcx = 1; ++sx.x; for (; srcx < src_w; ++srcx, ++sx.x) { current = SKIPSMImagePixelType(sa(sx)); sc0a[srcx] = sr1 + imul6(sr0) + current; sc0b[srcx] = (sr0 + current) * 4; sc1a[srcx] = SKIPSMImageZero; sc1b[srcx] = SKIPSMImageZero; sr1 = sr0; sr0 = current; } // extra column at end of first row if (wraparound) { current = SKIPSMImagePixelType(sa(sy)); if (dst_w_even) { sc0a[srcx] = sr1 + imul6(sr0) + current; sc0b[srcx] = (sr0 + current) * 4; } else { sc0a[srcx] = sr1 + imul6(sr0) + imul4(current); // sc*b[srcx] are irrelevant for odd-sized dst images in wraparound mode. } } else { sc0a[srcx] = sr1 + imul6(sr0); sc0b[srcx] = sr0 * 4; } sc1a[srcx] = SKIPSMImageZero; sc1b[srcx] = SKIPSMImageZero; } // dy = row 0 // dyy = row 1 ++dyy.y; // sy = row 1 srcy = 1; ++sy.y; // Second row if (src_h > 1) { // First column srcx = 0; sx = sy; sr0 = SKIPSMImagePixelType(sa(sx)); if (wraparound) { sr1 = SKIPSMImagePixelType(sa(sy, vigra::Diff2D(src_w - 1, 0))); if (!dst_w_even) { sr1 = imul4(sr1); } } else { sr1 = SKIPSMImageZero; } // sc*[0] are irrelevant srcx = 1; ++sx.x; dx = dy; dxx = dyy; // Second column if (src_w > 1) { if (wraparound) { if (dst_w_even) { SKIPSM_EXPAND(56, 56, 16, 16); } else { SKIPSM_EXPAND(77, 56, 22, 16); } } else { SKIPSM_EXPAND(49, 56, 14, 16); } // Main columns for (srcx = 2, ++sx.x; srcx < src_w; ++srcx, ++sx.x) { SKIPSM_EXPAND(56, 56, 16, 16); } // extra column at end of second row if (wraparound) { if (dst_w_even) { SKIPSM_EXPAND_COLUMN_END_WRAPAROUND_EVEN(56, 56, 16, 16); } else { SKIPSM_EXPAND_COLUMN_END_WRAPAROUND_ODD(77, 22); } } else { SKIPSM_EXPAND_COLUMN_END(49, 28, 14, 8); } } else { // Math works out exactly the same for wraparound and no wraparound when src_w ==1 SKIPSM_EXPAND_COLUMN_END(42, 28, 12, 8); } } else { // No Second Row // First Column srcx = 0; sr0 = SKIPSMImageZero; sr1 = SKIPSMImageZero; dx = dy; dxx = dyy; if (src_w > 1) { // Second Column srcx = 1; if (wraparound) { if (dst_w_even) { SKIPSM_EXPAND_ROW_END(48, 48, 8, 8); } else { SKIPSM_EXPAND_ROW_END(66, 48, 11, 8); } } else { SKIPSM_EXPAND_ROW_END(42, 48, 7, 8); } // Main columns for (srcx = 2; srcx < src_w; ++srcx) { SKIPSM_EXPAND_ROW_END(48, 48, 8, 8); } // extra column at end of row if (wraparound) { if (dst_w_even) { SKIPSM_EXPAND_ROW_COLUMN_END(48, 48, 8, 8); } else { SKIPSM_EXPAND_ROW_COLUMN_END(66, 48, 11, 8); } } else { SKIPSM_EXPAND_ROW_COLUMN_END(42, 24, 7, 4); } } else { // No Second Column // dst_w, dst_h must be at least 2 SKIPSM_EXPAND_ROW_COLUMN_END(36, 24, 6, 4); } delete [] sc0a; delete [] sc0b; delete [] sc1a; delete [] sc1b; return; } // dy = row 2 // dyy = row 3 dy.y += 2; dyy.y += 2; // sy = row 2 srcy = 2; ++sy.y; // Main Rows for (srcy = 2, sx = sy; srcy < src_h; ++srcy, ++sy.y, dy.y += 2, dyy.y += 2) { // First column srcx = 0; sx = sy; sr0 = SKIPSMImagePixelType(sa(sx)); if (wraparound) { sr1 = SKIPSMImagePixelType(sa(sy, vigra::Diff2D(src_w-1,0))); if (!dst_w_even) { sr1 = imul4(sr1); } } else { sr1 = SKIPSMImageZero; } // sc*[0] are irrelevant srcx = 1; ++sx.x; dx = dy; dxx = dyy; // Second column if (src_w > 1) { if (wraparound) { if (dst_w_even) { SKIPSM_EXPAND(64, 64, 16, 16); } else { SKIPSM_EXPAND(88, 64, 22, 16); } } else { SKIPSM_EXPAND(56, 64, 14, 16); } // Main columns for (srcx = 2, ++sx.x; srcx < src_w; ++srcx, ++sx.x) { SKIPSM_EXPAND(64, 64, 16, 16); } // extra column at end of row if (wraparound) { if (dst_w_even) { SKIPSM_EXPAND_COLUMN_END_WRAPAROUND_EVEN(64, 64, 16, 16); } else { SKIPSM_EXPAND_COLUMN_END_WRAPAROUND_ODD(88, 22); } } else { SKIPSM_EXPAND_COLUMN_END(56, 32, 14, 8); } } else { // No second column // dst_w must be at least 2 // Math works out exactly the same for wraparound and no wraparound when src_w == 1 SKIPSM_EXPAND_COLUMN_END(48, 32, 12, 8); } } // Extra row at end { srcx = 0; sr0 = SKIPSMImageZero; sr1 = SKIPSMImageZero; dx = dy; dxx = dyy; if (src_w > 1) { // Second Column srcx = 1; if (wraparound) { if (dst_w_even) { SKIPSM_EXPAND_ROW_END(56, 56, 8, 8); } else { SKIPSM_EXPAND_ROW_END(77, 56, 11, 8); } } else { SKIPSM_EXPAND_ROW_END(49, 56, 7, 8); } // Main columns for (srcx = 2; srcx < src_w; ++srcx) { SKIPSM_EXPAND_ROW_END(56, 56, 8, 8); } // extra column at end of row if (wraparound) { if (dst_w_even) { SKIPSM_EXPAND_ROW_COLUMN_END(56, 56, 8, 8); } else { SKIPSM_EXPAND_ROW_COLUMN_END(77, 56, 11, 8); } } else { SKIPSM_EXPAND_ROW_COLUMN_END(49, 28, 7, 4); } } else { // No Second Column // dst_w, dst_h must be at least 2 SKIPSM_EXPAND_ROW_COLUMN_END(42, 28, 6, 4); } } delete [] sc0a; delete [] sc0b; delete [] sc1a; delete [] sc1b; } // Functor that adds two values and de-promotes the result. // Used when collapsing a laplacian pyramid. // Explict fromPromote necessary to avoid overflow/underflow problems. template struct FromPromotePlusFunctorWrapper : public std::binary_function { inline T3 operator()(const T1& a, const T2& b) const { return vigra::NumericTraits::fromPromote(a + b); } }; // Version using argument object factories. template inline static void expand(bool add, bool wraparound, vigra::triple src, vigra::triple dest) { typedef typename DestAccessor::value_type DestPixelType; if (add) { expand(add, wraparound, src.first, src.second, src.third, dest.first, dest.second, dest.third, FromPromotePlusFunctorWrapper()); } else { expand(add, wraparound, src.first, src.second, src.third, dest.first, dest.second, dest.third, std::minus()); } } //////////////////////////////////////////////////////////////////////////////////////////////// // // Gaussian Pyramid // //////////////////////////////////////////////////////////////////////////////////////////////// /** Calculate the Gaussian pyramid for the given SrcImage/AlphaImage pair. */ template std::vector* gaussianPyramid(unsigned int numLevels, bool wraparound, typename SrcImageType::const_traverser src_upperleft, typename SrcImageType::const_traverser src_lowerright, typename SrcImageType::ConstAccessor sa, typename AlphaImageType::const_traverser alpha_upperleft, typename AlphaImageType::ConstAccessor aa) { std::vector* gp = new std::vector(); // Size of pyramid level 0 int w = src_lowerright.x - src_upperleft.x; int h = src_lowerright.y - src_upperleft.y; // Pyramid level 0 PyramidImageType* gp0 = new PyramidImageType(w, h); // Copy src image into gp0, using fixed-point conversions. copyToPyramidImage (src_upperleft, src_lowerright, sa, gp0->upperLeft(), gp0->accessor()); gp->push_back(gp0); if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << command << ": info: generating Gaussian pyramid: g0"; } // Make remaining levels. PyramidImageType* lastGP = gp0; AlphaImageType* lastA = nullptr; for (unsigned int l = 1; l < numLevels; l++) { if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << " g" << l; std::cerr.flush(); } // Size of next level w = (w + 1) >> 1; h = (h + 1) >> 1; // Next pyramid level PyramidImageType* gpn = new PyramidImageType(w, h); AlphaImageType* nextA = new AlphaImageType(w, h); if (lastA == nullptr) { reduce (wraparound, srcImageRange(*lastGP), maskIter(alpha_upperleft, aa), destImageRange(*gpn), destImageRange(*nextA)); } else { reduce (wraparound, srcImageRange(*lastGP), maskImage(*lastA), destImageRange(*gpn), destImageRange(*nextA)); } gp->push_back(gpn); lastGP = gpn; delete lastA; lastA = nextA; } delete lastA; if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << std::endl; } return gp; } // Version using argument object factories. template inline std::vector* gaussianPyramid(unsigned int numLevels, bool wraparound, vigra::triple src, vigra::pair alpha) { return gaussianPyramid(numLevels, wraparound, src.first, src.second, src.third, alpha.first, alpha.second); } /** Calculate the Gaussian pyramid for the given image (without an alpha channel). */ template std::vector* gaussianPyramid(unsigned int numLevels, bool wraparound, typename SrcImageType::const_traverser src_upperleft, typename SrcImageType::const_traverser src_lowerright, typename SrcImageType::ConstAccessor sa) { std::vector* gp = new std::vector(); // Size of pyramid level 0 int w = src_lowerright.x - src_upperleft.x; int h = src_lowerright.y - src_upperleft.y; // Pyramid level 0 PyramidImageType *gp0 = new PyramidImageType(w, h); // Copy src image into gp0, using fixed-point conversions. copyToPyramidImage (src_upperleft, src_lowerright, sa, gp0->upperLeft(), gp0->accessor()); gp->push_back(gp0); if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << command << ": info: generating Gaussian pyramid: g0"; } // Make remaining levels. PyramidImageType* lastGP = gp0; for (unsigned int l = 1; l < numLevels; l++) { if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << " g" << l; std::cerr.flush(); } // Size of next level w = (w + 1) >> 1; h = (h + 1) >> 1; // Next pyramid level PyramidImageType *gpn = new PyramidImageType(w, h); reduce(wraparound, srcImageRange(*lastGP), destImageRange(*gpn)); gp->push_back(gpn); lastGP = gpn; } if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << std::endl; } return gp; } // Version using argument object factories. template inline static std::vector* gaussianPyramid(unsigned int numLevels, bool wraparound, vigra::triple src) { return gaussianPyramid(numLevels, wraparound, src.first, src.second, src.third); } //////////////////////////////////////////////////////////////////////////////////////////////// // // Laplacian Pyramid // //////////////////////////////////////////////////////////////////////////////////////////////// /** Calculate the Laplacian pyramid of the given SrcImage/AlphaImage pair. */ template std::vector* laplacianPyramid(const char* exportName, unsigned int numLevels, bool wraparound, typename SrcImageType::const_traverser src_upperleft, typename SrcImageType::const_traverser src_lowerright, typename SrcImageType::ConstAccessor sa, typename AlphaImageType::const_traverser alpha_upperleft, typename AlphaImageType::ConstAccessor aa) { // First create a Gaussian pyramid. std::vector * gp = gaussianPyramid(numLevels, wraparound, src_upperleft, src_lowerright, sa, alpha_upperleft, aa); //exportPyramid(gp, exportName); if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << command << ": info: generating Laplacian pyramid:"; std::cerr.flush(); } // For each level, subtract the expansion of the next level. // Stop if there is no next level. for (unsigned int l = 0; l < (numLevels-1); l++) { if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << " l" << l; std::cerr.flush(); } //if (l == 4) { // int dst_w = (*((*gp)[l])).width(); // cout << "dst_w=" << dst_w << std::endl; // cout << std::endl << "pre-expand l4 gp:" << std::endl; // for (int y = 30; y < 35; y++) { // cout << "y=" << y << std::endl; // for (int x = -4; x < 4; ++x) { // int modX = (x < 0) ? x+dst_w : x; // cout << (*((*gp)[l]))(modX,y) << std::endl; // } // } // int src_w = (*((*gp)[l+1])).width(); // cout << "src_w=" << src_w << std::endl; // cout << std::endl << "l5 gp:" << std::endl; // for (int y = 15; y < 18; y++) { // cout << "y=" << y << std::endl; // for (int x = -2; x < 2; ++x) { // int modX = (x < 0) ? x+src_w : x; // cout << (*((*gp)[l+1]))(modX,y) << std::endl; // } // } //} expand(false, wraparound, srcImageRange(*((*gp)[l+1])), destImageRange(*((*gp)[l]))); //if (l == 4) { // int dst_w = (*((*gp)[l])).width(); // cout << std::endl << "post-expand l4 gp:" << std::endl; // for (int y = 30; y < 35; y++) { // cout << "y=" << y << std::endl; // for (int x = -4; x < 4; ++x) { // int modX = (x < 0) ? x+dst_w : x; // cout << (*((*gp)[l]))(modX,y) << std::endl; // } // } //} } if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << " l" << (numLevels-1) << std::endl; } //exportPyramid(gp, exportName); return gp; } // Version using argument object factories. template inline std::vector* laplacianPyramid(const char* exportName, unsigned int numLevels, bool wraparound, vigra::triple src, vigra::pair alpha) { return laplacianPyramid (exportName, numLevels, wraparound, src.first, src.second, src.third, alpha.first, alpha.second); } //////////////////////////////////////////////////////////////////////////////////////////////// // // Export pyramids to (TIFF) file // //////////////////////////////////////////////////////////////////////////////////////////////// /** Collapse the given Laplacian pyramid. */ template void collapsePyramid(bool wraparound, std::vector* p) { if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << command << ": info: collapsing Laplacian pyramid: " << "l" << p->size() - 1; std::cerr.flush(); } // For each level, add the expansion of the next level. // Work backwards from the smallest level to the largest. for (int l = (p->size()-2); l >= 0; l--) { if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << " l" << l; std::cerr.flush(); } expand(true, wraparound, srcImageRange(*((*p)[l + 1])), destImageRange(*((*p)[l]))); } if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << std::endl; } } // Export a scalar pyramid as a set of UINT16 tiff files. template void exportPyramid(std::vector* v, const char* prefix, vigra::VigraTrueType) { typedef typename PyramidImageType::value_type PyramidValueType; //for (unsigned int i = 0; i < (v->size() - 1); i++) { // // Clear all levels except last. // initImage(destImageRange(*((*v)[i])), vigra::NumericTraits::zero()); //} //collapsePyramid(false, v); for (unsigned int i = 0; i < v->size(); i++) { char filenameBuf[512]; snprintf(filenameBuf, 512, "%s%04u.tif", prefix, i); // Rescale the pyramid values to fit in UINT16. vigra::UInt16Image usPyramid((*v)[i]->width(), (*v)[i]->height()); vigra::omp::transformImage(srcImageRange(*((*v)[i])), destImage(usPyramid), vigra::linearRangeMapping(vigra::NumericTraits::min(), vigra::NumericTraits::max(), vigra::NumericTraits::min(), vigra::NumericTraits::max())); vigra::ImageExportInfo info(filenameBuf); vigra::exportImage(srcImageRange(usPyramid), info); } } // Export a vector pyramid as a set of UINT16 tiff files. template void exportPyramid(std::vector *v, const char *prefix, vigra::VigraFalseType) { typedef typename PyramidImageType::value_type PyramidVectorType; typedef typename PyramidVectorType::value_type PyramidValueType; //for (unsigned int i = 0; i < (v->size() - 1); i++) { // // Clear all levels except last. // initImage(destImageRange(*((*v)[i])), vigra::NumericTraits::zero()); //} //collapsePyramid(false, v); for (unsigned int i = 0; i < v->size(); i++) { char filenameBuf[512]; snprintf(filenameBuf, 512, "%s%04u.tif", prefix, i); // Rescale the pyramid values to fit in UINT16. vigra::UInt16RGBImage usPyramid((*v)[i]->width(), (*v)[i]->height()); vigra::omp::transformImage(srcImageRange(*((*v)[i])), destImage(usPyramid), vigra::linearRangeMapping(PyramidVectorType(vigra::NumericTraits::min()), PyramidVectorType(vigra::NumericTraits::max()), typename vigra::UInt16RGBImage::value_type(vigra::NumericTraits::min()), typename vigra::UInt16RGBImage::value_type(vigra::NumericTraits::max()))); vigra::ImageExportInfo info(filenameBuf); vigra::exportImage(srcImageRange(usPyramid), info); } } // Export a pyramid as a set of UINT16 tiff files. template void exportPyramid(std::vector* v, const char* prefix) { typedef typename vigra::NumericTraits::isScalar pyramid_is_scalar; exportPyramid(v, prefix, pyramid_is_scalar()); } } // namespace enblend #endif // PYRAMID_H_INCLUDED_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/CMakeLists.txt0000644000175000017500000001176112676263420014537 00000000000000# This file is part of enblend/enfuse. # Licence details can be found in the file COPYING. # # Copyright (c) 2009-2015, Kornel Benko # , Ryan Sleevi # , Harry van der Wolf # # Get the version-string from ${TOP_SRC_DIR}/VERSION add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/signature.h" COMMAND ${PERL_EXECUTABLE} -I"${TOP_SRC_DIR}/src" "${TOP_SRC_DIR}/src/gen_sig" "--extra=${ENBLEND_MAJOR_VERSION}.${ENBLEND_MINOR_VERSION}-${ENBLEND_CHANGESET}" ">" "${CMAKE_CURRENT_BINARY_DIR}/signature.h" DEPENDS "${TOP_SRC_DIR}/src/gen_sig" "${TOP_SRC_DIR}/VERSION" ) add_custom_target(signature DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/signature.h") include_directories(${TOP_SRC_DIR}/src) set(ENBLEND_SOURCES fillpolygon.hxx functoraccessor.hxx rect2d.hxx stride.hxx anneal.h assemble.h blend.h bounds.h common.h enblend.h enblend.cc fixmath.h global.h graphcut.h maskcommon.h masktypedefs.h mask.h postoptimizer.h nearest.h numerictraits.h opencl.h opencl.cc opencl_vigra.h openmp_def.h openmp_lock.h openmp_vigra.h path.h pyramid.h alternativepercentage.h alternativepercentage.cc error_message.h error_message.cc filenameparse.h filenameparse.cc filespec.h filespec.cc introspection.h introspection.cc mersenne.h mersenne.cc parameter.h parameter.cc self_test.h self_test.cc tiff_message.h tiff_message.cc timer.h timer.cc minimizer.h minimizer.cc muopt.h ) set(ENFUSE_SOURCES functoraccessor.hxx rect2d.hxx stride.hxx assemble.h blend.h bounds.h common.h exposure_weight_base.h exposure_weight.h exposure_weight.cc enfuse.h enfuse.cc fixmath.h global.h mga.h numerictraits.h opencl.h opencl.cc opencl_vigra.h opencl_exposure_weight.h opencl_exposure_weight.cc openmp_def.h openmp_lock.h openmp_vigra.h pyramid.h alternativepercentage.h alternativepercentage.cc error_message.h error_message.cc filenameparse.h filenameparse.cc filespec.h filespec.cc introspection.h introspection.cc mersenne.h mersenne.cc parameter.h parameter.cc self_test.h self_test.cc tiff_message.h tiff_message.cc timer.h timer.cc minimizer.h minimizer.cc muopt.h ) set(additional_libs) if (WIN32) list(APPEND ENBLEND_SOURCES win32helpers/delayHelper.h) list(APPEND ENFUSE_SOURCES win32helpers/delayHelper.h) add_subdirectory(win32helpers) list(APPEND additional_libs getopt) endif() add_subdirectory(layer_selection) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/layer_selection) list(APPEND additional_libs layer_selection) add_subdirectory(dynamic_loader) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/dynamic_loader) add_definitions(${DL_DEFINITION}) list(APPEND additional_libs dynamic_loader) include_directories(${CMAKE_CURRENT_BINARY_DIR}) message(STATUS "Boost_FOUND = ${Boost_FOUND}") message(STATUS "OpenMP_CXX_FLAGS = ${OpenMP_CXX_FLAGS}") add_executable(enblend ${ENBLEND_SOURCES}) add_executable(enfuse ${ENFUSE_SOURCES}) add_dependencies(enblend signature) add_dependencies(enfuse signature) target_compile_definitions(enblend PUBLIC "-DENBLEND_SOURCE") target_compile_definitions(enfuse PUBLIC "-DENFUSE_SOURCE") if(OpenMP_CXX_FLAGS AND NOT MSVC) set_target_properties(enblend PROPERTIES LINK_FLAGS ${OpenMP_CXX_FLAGS}) set_target_properties(enfuse PROPERTIES LINK_FLAGS ${OpenMP_CXX_FLAGS}) message(STATUS "Adding PROPERTIES LINK_FLAGS to enblend and enfuse") endif(OpenMP_CXX_FLAGS AND NOT MSVC) target_link_libraries(enblend ${common_libs} ${additional_libs}) target_link_libraries(enfuse ${common_libs} ${additional_libs}) install(TARGETS enblend enfuse DESTINATION bin CONFIGURATIONS Release RelWithDebInfo MinSizeRel) if(NOT WIN32) # create enblend.1 and enfuse.1 if(NOT MANDIR AND NOT $ENV{MANDIR} STREQUAL "") set(MANDIR "$ENV{MANDIR}") elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "NetBSD") set(MANDIR "man") else(NOT MANDIR AND NOT $ENV{MANDIR} STREQUAL "") set(MANDIR "share/man") endif() find_program(HELP2MAN_EXE "help2man") if (NOT DOC OR ${HELP2MAN_EXE} MATCHES "-NOTFOUND") INSTALL(FILES enblend.1 enfuse.1 DESTINATION ${MANDIR}/man1) else() project(man) add_custom_command( OUTPUT "${CMAKE_BINARY_DIR}/src/enblend.1" COMMAND "${HELP2MAN_EXE}" "--output=enblend.1" "${CMAKE_BINARY_DIR}/bin/enblend" DEPENDS "${CMAKE_BINARY_DIR}/bin/enblend" ) add_custom_command( OUTPUT "${CMAKE_BINARY_DIR}/src/enfuse.1" COMMAND "${HELP2MAN_EXE}" "--output=enfuse.1" "${CMAKE_BINARY_DIR}/bin/enfuse" DEPENDS "${CMAKE_BINARY_DIR}/bin/enfuse" ) add_custom_target(man ALL DEPENDS enblend.1 enfuse.1) add_dependencies(man enblend enfuse) INSTALL(FILES ${CMAKE_BINARY_DIR}/src/enblend.1 ${CMAKE_BINARY_DIR}/src/enfuse.1 DESTINATION ${MANDIR}/man1) endif() endif() enblend-enfuse-4.2/src/layer_selection/0000755000175000017500000000000012676432767015246 500000000000000enblend-enfuse-4.2/src/layer_selection/selector.cc0000644000175000017500000005251012641706002017272 00000000000000/* * Copyright (C) 2010-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include // std::isspace(), std::tolower() #include // WHILE DEBUGGING #include // std::unique_ptr #include #ifdef HAVE_CONFIG_H #include #endif #include "selector.h" #define NUMERIC_OPTION_DELIMITERS ";:/" // FIXME: Already defined on "common.h". extern const std::string command; template static std::string mapconcat(iterator a_begin, iterator an_end, unary_function a_function, const std::string& a_separator) { if (a_begin == an_end) { return std::string(); } else { std::string result(a_function(*a_begin)); while (++a_begin != an_end) { result.append(a_separator).append(a_function(*a_begin)); } return result; } } namespace selector { std::string AllLayers::name() const { return "all-layers"; } std::string AllLayers::description() const { return "select all layers in any image;"; } layer_ordered_list_t AllLayers::viable_layers(const ImageListInformation* an_image_info, const std::string& a_filename) { const ImageInfo* image_info = an_image_info->image_info_on(a_filename); layer_ordered_list_t result; for (unsigned i = 1; i <= image_info->number_of_layers(); ++i) { result.push_back(i); } return result; } std::string FirstLayer::name() const { return "first-layer"; } std::string FirstLayer::description() const { return "select only first layer in each (multi-)layer image;"; } std::string LastLayer::name() const { return "last-layer"; } std::string LastLayer::description() const { return "select only last layer in each (multi-)layer image;"; } layer_ordered_list_t LastLayer::viable_layers(const ImageListInformation* an_image_info, const std::string& a_filename) { const ImageInfo* image_info = an_image_info->image_info_on(a_filename); return layer_ordered_list_t(1, image_info->number_of_layers()); } bool LastLayer::select(const ImageListInformation* an_image_info, const std::string& a_filename, unsigned a_layer_index) { const ImageInfo* image_info = an_image_info->image_info_on(a_filename); return a_layer_index == image_info->number_of_layers(); } std::string LargestLayer::name() const { return "largest-layer"; } std::string LargestLayer::description() const { return "select largest layer in each (multi-)layer image;"; } static unsigned find_largest_layer(const ImageListInformation* an_image_info, const std::string& a_filename) { const ImageInfo* image_info = an_image_info->image_info_on(a_filename); const unsigned number_of_layers = image_info->number_of_layers(); unsigned max_index = 0; int max_area = -1; for (unsigned i = 0; i != number_of_layers; ++i) { const LayerInfo* layer_info = an_image_info->layer_info_on(a_filename, i); const int area = layer_info->width * layer_info->height; if (area > max_area) { max_area = area; max_index = i; } } return max_index; } bool LargestLayer::select(const ImageListInformation* an_image_info, const std::string& a_filename, unsigned a_layer_index) { cache_t::const_iterator index = cache_.find(a_filename); unsigned max_index; if (index == cache_.end()) { max_index = 1 + find_largest_layer(an_image_info, a_filename); cache_.insert(cache_t::value_type(a_filename, max_index)); } else { max_index = index->second; } return a_layer_index == max_index; } layer_ordered_list_t LargestLayer::viable_layers(const ImageListInformation* an_image_info, const std::string& a_filename) { cache_t::const_iterator index = cache_.find(a_filename); unsigned max_index; if (index == cache_.end()) { max_index = 1 + find_largest_layer(an_image_info, a_filename); cache_.insert(cache_t::value_type(a_filename, max_index)); } else { max_index = index->second; } return layer_ordered_list_t(1, max_index); } std::string NoLayer::name() const { return "no-layer"; } std::string NoLayer::description() const { return "do not select any layer from any image;"; } // Implementation Note: We cannot use the new, unified // initialization syntax with curlies here, because it employs // copy-semantics. Unique-ptr requires move-semantics, though. algorithm_list algorithms; namespace initialization { struct initialize_algorithms { initialize_algorithms() { algorithms.emplace_back(new AllLayers); algorithms.emplace_back(new FirstLayer); algorithms.emplace_back(new LastLayer); algorithms.emplace_back(new LargestLayer); algorithms.emplace_back(new NoLayer); // NOTE: `IndexedLayer' does _not_ belong here! } } algorithms_initializer; } // namespace initialization algorithm_list::const_iterator find_by_id(id_t an_id) { algorithm_list::const_iterator algorithm = std::find_if(algorithms.begin(), algorithms.end(), [&an_id](const algorithm_list::value_type& x) {return x->id() == an_id;}); assert(algorithm != algorithms.end()); return algorithm; } algorithm_list::const_iterator find_by_name(const std::string& a_name) { algorithm_list::const_iterator algorithm = std::find_if(algorithms.begin(), algorithms.end(), [&a_name](const algorithm_list::value_type& x) {return x->name() == a_name;}); return algorithm; } //////////////////////////////////////////////////////////////////////// static const std::string range_separator(".."); //< layer-range-separator .. static const std::string empty_index_symbol("_"); //< layer-range-empty-index-symbol \char95 static const std::string reverse_keyword("reverse"); //< layer-range-reverse-keyword reverse struct Index { virtual ~Index() {} virtual Index* clone() const = 0; virtual index_list_t values(int a_maximum_index) const = 0; virtual std::string as_string() const = 0; }; struct SingletonIndex : public Index { virtual int value(int a_forward_index) const = 0; virtual void set_first_position(bool is_first) {} virtual bool get_first_position() const {assert(false); return true;} index_list_t values(int a_maximum_index) const { return index_list_t(1, value(a_maximum_index)); } }; class ForwardIndex : public SingletonIndex { public: ForwardIndex() = delete; ForwardIndex(int a_forward_index) : index_(a_forward_index) {} ForwardIndex* clone() const {return new ForwardIndex(*this);} int value(int) const {return index_;} std::string as_string() const {return std::to_string(index_);} private: const int index_; }; class BackwardsIndex : public SingletonIndex { public: BackwardsIndex() = delete; BackwardsIndex(int a_backwards_index) : index_(a_backwards_index) {} BackwardsIndex* clone() const {return new BackwardsIndex(*this);} int value(int a_maximum_index) const {return a_maximum_index + index_ + 1;} std::string as_string() const {return std::to_string(index_);} private: const int index_; }; class EmptyIndex : public SingletonIndex { public: EmptyIndex* clone() const override {return new EmptyIndex(*this);} int value(int a_maximum_index) const override {return get_first_position() ? 1 : a_maximum_index;} std::string as_string() const override {return empty_index_symbol;} void set_first_position(bool is_first) override {is_first_ = is_first;} bool get_first_position() const override {return is_first_;} private: bool is_first_; }; class RangeOfIndices : public Index { public: RangeOfIndices() = delete; RangeOfIndices(const SingletonIndex* a_begin, const SingletonIndex* an_end, int a_stride); RangeOfIndices(const RangeOfIndices& another_range_of_indices); RangeOfIndices& operator=(const RangeOfIndices&) = delete; ~RangeOfIndices(); RangeOfIndices* clone() const {return new RangeOfIndices(*this);} std::string as_string() const; index_list_t values(int a_maximum_index) const; private: SingletonIndex* begin_; SingletonIndex* end_; const int stride_; }; RangeOfIndices::RangeOfIndices(const SingletonIndex* a_begin, const SingletonIndex* an_end, int a_stride) : begin_(static_cast(a_begin->clone())), end_(static_cast(an_end->clone())), stride_(a_stride) { assert(a_stride != 0); begin_->set_first_position(true); end_->set_first_position(false); } RangeOfIndices::RangeOfIndices(const RangeOfIndices& another_range_of_indices) : begin_(static_cast(another_range_of_indices.begin_->clone())), end_(static_cast(another_range_of_indices.end_->clone())), stride_(another_range_of_indices.stride_) {} RangeOfIndices::~RangeOfIndices() { delete begin_; delete end_; } std::string RangeOfIndices::as_string() const { const std::string direction(stride_ >= 1 ? "" : reverse_keyword + " "); return direction + begin_->as_string() + range_separator + end_->as_string(); } index_list_t RangeOfIndices::values(int a_maximum_index) const { const int begin = begin_->value(a_maximum_index); const int end = end_->value(a_maximum_index); const int actual_begin = stride_ >= 1 ? begin : end; const int actual_end = stride_ >= 1 ? end : begin; #ifdef DEBUG_FILESPEC std::cout << "+ RangeOfIndices::values(" << a_maximum_index << "): actual_begin = " << actual_begin << ", actual_end = " << actual_end << ", stride = " << stride_ << "\n"; #endif index_list_t result; int i = actual_begin; while (stride_ >= 1 ? i <= actual_end : i >= actual_end) { result.push_back(i); i += stride_; } return result; } // http://www.boost.org/doc/libs/1_58_0/libs/tokenizer/ typedef boost::char_separator separator_t; typedef boost::tokenizer tokenizer_t; inline static bool is_whitespace_or_empty(const std::string& a_string) { for (auto c : a_string) { if (!(std::isspace(c) || c == empty_index_symbol[0])) { return false; } } return true; } static SingletonIndex* parse_singleton(const std::string& a_token) { if (is_whitespace_or_empty(a_token)) { return new EmptyIndex(); } try { std::unique_ptr tail_position(new std::size_t); const int n = std::stoi(a_token, tail_position.get()); // The condition below reads: ``If the tail-position, // i.e. the first character we did not parse, equals the // size of the token, we have really parsed the token in // its entirety.'' Note: This is safer than to code // a_token[*tail_position] == 0 // which relies on a terminal character promotable to 0. if (*tail_position == a_token.size()) { if (n >= 1) { return new ForwardIndex(n); } else if (n <= -1) { return new BackwardsIndex(n); } else { std::cerr << command << ": zero (\"" << a_token << "\") is illegal as a layer index\n"; } } else { std::cerr << command << ": trailing garbage \"" << a_token.substr(*tail_position) << "\" after integer " << n << "\n"; } } catch (std::invalid_argument) { std::cerr << command << ": invalid integer \"" << a_token << "\"\n"; } catch (std::out_of_range) { std::cerr << command << ": number " << a_token << " is outside of the range of integers\n"; } return nullptr; } LayerSpecification::LayerSpecification(const std::string& a_layer_specification) { static const separator_t separator(NUMERIC_OPTION_DELIMITERS, ""); tokenizer_t tokenizer(a_layer_specification, separator); int token_number = 1; for (tokenizer_t::iterator token = tokenizer.begin(); token != tokenizer.end(); ++token) { const std::string::size_type range_separator_position = token->find(range_separator); std::pair prefix_count = std::mismatch(token->begin(), token->end(), reverse_keyword.begin(), [](std::string::value_type v1, std::string::value_type v2) {return tolower(v1) == tolower(v2);}); if (range_separator_position == std::string::npos) { if (prefix_count.first > token->begin()) { std::cerr << command << ": layer index, #" << token_number << " does not take \"reverse\" keyword in layer specification \"" << a_layer_specification << "\"\n"; exit(1); } SingletonIndex* possible_index(parse_singleton(*token)); if (possible_index == nullptr) { std::cerr << command << ": info: cannot parse layer index, #" << token_number << " in layer specification \"" << a_layer_specification << "\"\n"; exit(1); } else { indices_.push_back(possible_index); } } else { const size_t prefix_length = prefix_count.first - token->begin(); const bool forward_range = prefix_count.first == token->begin(); #ifdef DEBUG_FILESPEC std::cout << "+ LayerSpecification::LayerSpecification(const std::string&): " << " token = <" << *token << ">, reverse_keyword = <" << reverse_keyword << ">\n" << "+ LayerSpecification::LayerSpecification(const std::string&): " << "prefix_length = " << prefix_length << ", 1st = <" << token->substr(prefix_length, range_separator_position - prefix_length) << ">, 2nd = <" << token->substr(range_separator_position + range_separator.length()) << ">\n"; #endif std::unique_ptr first_index(parse_singleton(token->substr(prefix_length, range_separator_position - prefix_length))); std::unique_ptr second_index(parse_singleton(token->substr(range_separator_position + range_separator.length()))); if (first_index.get() == nullptr) { std::cerr << command << ": info: cannot parse first bound of layer range, #" << token_number << " in layer specification \"" << a_layer_specification << "\"\n"; exit(1); } else if (second_index.get() == nullptr) { std::cerr << command << ": info: cannot parse second bound of layer range, #" << token_number << " in layer specification \"" << a_layer_specification << "\"\n"; exit(1); } else { if (forward_range) { indices_.push_back(new RangeOfIndices(first_index.get(), second_index.get(), 1)); } else { indices_.push_back(new RangeOfIndices(first_index.get(), second_index.get(), -1)); } } } ++token_number; } } LayerSpecification::LayerSpecification(const LayerSpecification& another_layer_specification) : indices_(abstract_index_list_t(another_layer_specification.indices_.size(), nullptr)) { std::transform(another_layer_specification.indices_.begin(), another_layer_specification.indices_.end(), indices_.begin(), [](Index* x) {return x->clone();}); } LayerSpecification::~LayerSpecification() { std::for_each(indices_.begin(), indices_.end(), [](Index* x) {delete x;}); } index_list_t LayerSpecification::values(int a_maximum_index) const { index_list_t result; for (auto i : indices_) { const index_list_t is(i->values(a_maximum_index)); result.insert(result.end(), is.begin(), is.end()); } return result; } std::string LayerSpecification::as_string() const { return indices_.empty() ? std::string("") : mapconcat(indices_.begin(), indices_.end(), [](const Index* x) {return x->as_string();}, ":"); } //////////////////////////////////////////////////////////////////////// IndexedLayer::IndexedLayer(const std::string& a_layer_specification) : layer_spec_(LayerSpecification(a_layer_specification)) {} std::string IndexedLayer::name() const { return std::string("indexed-layer ") + layer_spec_.as_string(); } std::string IndexedLayer::description() const { return "select layers from image by a given tuple of indexes;"; } LayerSpecification IndexedLayer::layer_spec() const { return layer_spec_; } bool IndexedLayer::select(const ImageListInformation* an_image_info, const std::string& a_filename, unsigned a_layer_index) { const ImageInfo* image_info = an_image_info->image_info_on(a_filename); const unsigned number_of_layers = image_info->number_of_layers(); const index_list_t selection = layer_spec_.values(number_of_layers); if (selection.empty()) { std::cerr << command << ": info: indexed layer selection " << layer_spec_.as_string() << " contains no index\n"; } if (a_layer_index > number_of_layers) { std::cerr << command << ": warning: " << "layer index " << a_layer_index << " is larger than number of layers " << number_of_layers << "\n"; } return std::find(selection.begin(), selection.end(), a_layer_index) != selection.end(); } layer_ordered_list_t IndexedLayer::viable_layers(const ImageListInformation* an_image_info, const std::string& a_filename) { const ImageInfo* image_info = an_image_info->image_info_on(a_filename); const unsigned number_of_layers = image_info->number_of_layers(); const index_list_t selection = layer_spec_.values(number_of_layers); layer_ordered_list_t result; std::copy(selection.begin(), selection.end(), std::back_inserter(result)); return result; } } // end namespace selector enblend-enfuse-4.2/src/layer_selection/selector.h0000644000175000017500000001365012641706002017136 00000000000000/* * Copyright (C) 2010-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SELECTOR_H_ #define SELECTOR_H_ #include #include #include #include #include #include "info.h" #include "layer_selection.h" namespace selector { enum class id_t { AllLayersId, FirstLayerId, LastLayerId, LargestLayerId, NoLayerId, IndexedLayerId }; typedef std::vector layer_ordered_list_t; struct Abstract { Abstract() {} virtual ~Abstract() {} virtual id_t id() const = 0; virtual std::string name() const = 0; virtual std::string description() const = 0; virtual bool select(const ImageListInformation* an_image_info, const std::string& a_filename, unsigned a_layer_index) = 0; virtual layer_ordered_list_t viable_layers(const ImageListInformation* an_image_info, const std::string& a_filename) = 0; }; class AllLayers : public Abstract { public: id_t id() const {return id_t::AllLayersId;} std::string name() const; std::string description() const; bool select(const ImageListInformation*, const std::string&, unsigned) {return true;} layer_ordered_list_t viable_layers(const ImageListInformation* an_image_info, const std::string& a_filename); }; class FirstLayer : public Abstract { public: id_t id() const {return id_t::FirstLayerId;} std::string name() const; std::string description() const; bool select(const ImageListInformation*, const std::string&, unsigned a_layer_index) { return a_layer_index == 1; } layer_ordered_list_t viable_layers(const ImageListInformation*, const std::string&) { return layer_ordered_list_t(1, 1); } }; class LastLayer : public Abstract { public: id_t id() const {return id_t::LastLayerId;} std::string name() const; std::string description() const; bool select(const ImageListInformation* an_image_info, const std::string& a_filename, unsigned a_layer_index); layer_ordered_list_t viable_layers(const ImageListInformation* an_image_info, const std::string& a_filename); }; class LargestLayer : public Abstract { typedef std::map cache_t; public: id_t id() const {return id_t::LargestLayerId;} std::string name() const; std::string description() const; bool select(const ImageListInformation* an_image_info, const std::string& a_filename, unsigned a_layer_index); layer_ordered_list_t viable_layers(const ImageListInformation* an_image_info, const std::string& a_filename); private: cache_t cache_; }; class NoLayer : public Abstract { public: id_t id() const {return id_t::NoLayerId;} std::string name() const; std::string description() const; bool select(const ImageListInformation*, const std::string&, unsigned) {return false;} layer_ordered_list_t viable_layers(const ImageListInformation*, const std::string&) { return layer_ordered_list_t(); } }; typedef std::list > algorithm_list; extern algorithm_list algorithms; algorithm_list::const_iterator find_by_id(id_t an_id); algorithm_list::const_iterator find_by_name(const std::string& a_name); //////////////////////////////////////////////////////////////////////// typedef std::vector index_list_t; struct Index; // forward declaration class LayerSpecification { public: LayerSpecification() = delete; LayerSpecification(const std::string& a_layer_specification); LayerSpecification(const LayerSpecification&); LayerSpecification& operator=(const LayerSpecification&) = delete; ~LayerSpecification(); index_list_t values(int a_maximum_index) const; std::string as_string() const; private: typedef std::vector abstract_index_list_t; abstract_index_list_t indices_; }; class IndexedLayer : public Abstract { public: IndexedLayer() = delete; explicit IndexedLayer(const std::string& a_layer_specification); id_t id() const {return id_t::IndexedLayerId;} std::string name() const; std::string description() const; LayerSpecification layer_spec() const; bool select(const ImageListInformation* an_image_info, const std::string& a_filename, unsigned a_layer_index); layer_ordered_list_t viable_layers(const ImageListInformation* an_image_info, const std::string& a_filename); private: const LayerSpecification layer_spec_; }; } // end namespace selector #endif // SELECTOR_H_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/layer_selection/Makefile.am0000644000175000017500000000100412543557642017206 00000000000000AM_CPPFLAGS = $(EXTRACPPFLAGS) AM_CFLAGS = $(EXTRACFLAGS) AM_CXXFLAGS = $(EXTRACXXFLAGS) AM_LDFLAGS = $(EXTRALDFLAGS) noinst_LIBRARIES = liblayersel.a liblayersel_a_SOURCES = info.h info.cc \ layer_selection.h layer_selection.cc \ selector.h selector.cc liblayersel_a_CXXFLAGS = $(AM_CXXFLAGS) \ -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \ -I$(top_srcdir)/include -I$(top_srcdir)/src -I$(top_srcdir)/src/layer_selection enblend-enfuse-4.2/src/layer_selection/Makefile.in0000644000175000017500000006072312676432431017227 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/layer_selection DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/_ac_latex_test.m4 \ $(top_srcdir)/m4/ac_latex_class.m4 \ $(top_srcdir)/m4/ac_latex_package.m4 \ $(top_srcdir)/m4/ac_prog_ar.m4 \ $(top_srcdir)/m4/ac_prog_latex.m4 \ $(top_srcdir)/m4/ac_type_sig_atomic_t.m4 \ $(top_srcdir)/m4/ax_boost_base.m4 \ $(top_srcdir)/m4/ax_cxx_as_const.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/ax_openmp.m4 \ $(top_srcdir)/m4/ax_prog_perl_modules.m4 \ $(top_srcdir)/m4/ax_with_prog.m4 $(top_srcdir)/m4/lrint.m4 \ $(top_srcdir)/m4/lrintf.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = liblayersel_a_AR = $(AR) $(ARFLAGS) liblayersel_a_LIBADD = am_liblayersel_a_OBJECTS = liblayersel_a-info.$(OBJEXT) \ liblayersel_a-layer_selection.$(OBJEXT) \ liblayersel_a-selector.$(OBJEXT) liblayersel_a_OBJECTS = $(am_liblayersel_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(liblayersel_a_SOURCES) DIST_SOURCES = $(liblayersel_a_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONVERT = @CONVERT@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_IMPLEMENTATION = @DL_IMPLEMENTATION@ DOT = @DOT@ DVIPDF = @DVIPDF@ DVIPS = @DVIPS@ DYNAMIC_TEX_PREAMBLE = @DYNAMIC_TEX_PREAMBLE@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_LIBS = @EXTRA_LIBS@ GNUPLOT = @GNUPLOT@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_INLINE = @HAVE_INLINE@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LATEX = @LATEX@ LATEX2HTML = @LATEX2HTML@ LATEX2HTML_LIBDIR = @LATEX2HTML_LIBDIR@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ M4 = @M4@ MAKEINDEX = @MAKEINDEX@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ OPENEXR_LIBS = @OPENEXR_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SPLITHTML = @SPLITHTML@ STRIP = @STRIP@ SVGCONVERT = @SVGCONVERT@ TEXLOGANALYSER = @TEXLOGANALYSER@ VERSION = @VERSION@ VIGRAIMPEX_LIB = @VIGRAIMPEX_LIB@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ amsmath = @amsmath@ bindir = @bindir@ bold_extra = @bold_extra@ boretti_classesansparametre = @boretti_classesansparametre@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ color = @color@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enumitem = @enumitem@ exec_prefix = @exec_prefix@ float = @float@ footnote = @footnote@ graphicx = @graphicx@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hyperref = @hyperref@ hyphenat = @hyphenat@ ifpdf = @ifpdf@ includedir = @includedir@ index = @index@ infodir = @infodir@ install_sh = @install_sh@ latex = @latex@ latexsym = @latexsym@ libdir = @libdir@ libexecdir = @libexecdir@ listings = @listings@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ microtype = @microtype@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ ragged2e = @ragged2e@ refrep = @refrep@ report = @report@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shorttoc = @shorttoc@ srcdir = @srcdir@ suffix = @suffix@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ url = @url@ xstring = @xstring@ AM_CPPFLAGS = $(EXTRACPPFLAGS) AM_CFLAGS = $(EXTRACFLAGS) AM_CXXFLAGS = $(EXTRACXXFLAGS) AM_LDFLAGS = $(EXTRALDFLAGS) noinst_LIBRARIES = liblayersel.a liblayersel_a_SOURCES = info.h info.cc \ layer_selection.h layer_selection.cc \ selector.h selector.cc liblayersel_a_CXXFLAGS = $(AM_CXXFLAGS) \ -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \ -I$(top_srcdir)/include -I$(top_srcdir)/src -I$(top_srcdir)/src/layer_selection all: all-am .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/layer_selection/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/layer_selection/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) liblayersel.a: $(liblayersel_a_OBJECTS) $(liblayersel_a_DEPENDENCIES) $(EXTRA_liblayersel_a_DEPENDENCIES) $(AM_V_at)-rm -f liblayersel.a $(AM_V_AR)$(liblayersel_a_AR) liblayersel.a $(liblayersel_a_OBJECTS) $(liblayersel_a_LIBADD) $(AM_V_at)$(RANLIB) liblayersel.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblayersel_a-info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblayersel_a-layer_selection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblayersel_a-selector.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` liblayersel_a-info.o: info.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblayersel_a_CXXFLAGS) $(CXXFLAGS) -MT liblayersel_a-info.o -MD -MP -MF $(DEPDIR)/liblayersel_a-info.Tpo -c -o liblayersel_a-info.o `test -f 'info.cc' || echo '$(srcdir)/'`info.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblayersel_a-info.Tpo $(DEPDIR)/liblayersel_a-info.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='info.cc' object='liblayersel_a-info.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblayersel_a_CXXFLAGS) $(CXXFLAGS) -c -o liblayersel_a-info.o `test -f 'info.cc' || echo '$(srcdir)/'`info.cc liblayersel_a-info.obj: info.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblayersel_a_CXXFLAGS) $(CXXFLAGS) -MT liblayersel_a-info.obj -MD -MP -MF $(DEPDIR)/liblayersel_a-info.Tpo -c -o liblayersel_a-info.obj `if test -f 'info.cc'; then $(CYGPATH_W) 'info.cc'; else $(CYGPATH_W) '$(srcdir)/info.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblayersel_a-info.Tpo $(DEPDIR)/liblayersel_a-info.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='info.cc' object='liblayersel_a-info.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblayersel_a_CXXFLAGS) $(CXXFLAGS) -c -o liblayersel_a-info.obj `if test -f 'info.cc'; then $(CYGPATH_W) 'info.cc'; else $(CYGPATH_W) '$(srcdir)/info.cc'; fi` liblayersel_a-layer_selection.o: layer_selection.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblayersel_a_CXXFLAGS) $(CXXFLAGS) -MT liblayersel_a-layer_selection.o -MD -MP -MF $(DEPDIR)/liblayersel_a-layer_selection.Tpo -c -o liblayersel_a-layer_selection.o `test -f 'layer_selection.cc' || echo '$(srcdir)/'`layer_selection.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblayersel_a-layer_selection.Tpo $(DEPDIR)/liblayersel_a-layer_selection.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='layer_selection.cc' object='liblayersel_a-layer_selection.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblayersel_a_CXXFLAGS) $(CXXFLAGS) -c -o liblayersel_a-layer_selection.o `test -f 'layer_selection.cc' || echo '$(srcdir)/'`layer_selection.cc liblayersel_a-layer_selection.obj: layer_selection.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblayersel_a_CXXFLAGS) $(CXXFLAGS) -MT liblayersel_a-layer_selection.obj -MD -MP -MF $(DEPDIR)/liblayersel_a-layer_selection.Tpo -c -o liblayersel_a-layer_selection.obj `if test -f 'layer_selection.cc'; then $(CYGPATH_W) 'layer_selection.cc'; else $(CYGPATH_W) '$(srcdir)/layer_selection.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblayersel_a-layer_selection.Tpo $(DEPDIR)/liblayersel_a-layer_selection.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='layer_selection.cc' object='liblayersel_a-layer_selection.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblayersel_a_CXXFLAGS) $(CXXFLAGS) -c -o liblayersel_a-layer_selection.obj `if test -f 'layer_selection.cc'; then $(CYGPATH_W) 'layer_selection.cc'; else $(CYGPATH_W) '$(srcdir)/layer_selection.cc'; fi` liblayersel_a-selector.o: selector.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblayersel_a_CXXFLAGS) $(CXXFLAGS) -MT liblayersel_a-selector.o -MD -MP -MF $(DEPDIR)/liblayersel_a-selector.Tpo -c -o liblayersel_a-selector.o `test -f 'selector.cc' || echo '$(srcdir)/'`selector.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblayersel_a-selector.Tpo $(DEPDIR)/liblayersel_a-selector.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='selector.cc' object='liblayersel_a-selector.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblayersel_a_CXXFLAGS) $(CXXFLAGS) -c -o liblayersel_a-selector.o `test -f 'selector.cc' || echo '$(srcdir)/'`selector.cc liblayersel_a-selector.obj: selector.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblayersel_a_CXXFLAGS) $(CXXFLAGS) -MT liblayersel_a-selector.obj -MD -MP -MF $(DEPDIR)/liblayersel_a-selector.Tpo -c -o liblayersel_a-selector.obj `if test -f 'selector.cc'; then $(CYGPATH_W) 'selector.cc'; else $(CYGPATH_W) '$(srcdir)/selector.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblayersel_a-selector.Tpo $(DEPDIR)/liblayersel_a-selector.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='selector.cc' object='liblayersel_a-selector.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liblayersel_a_CXXFLAGS) $(CXXFLAGS) -c -o liblayersel_a-selector.obj `if test -f 'selector.cc'; then $(CYGPATH_W) 'selector.cc'; else $(CYGPATH_W) '$(srcdir)/selector.cc'; fi` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: enblend-enfuse-4.2/src/layer_selection/info.h0000644000175000017500000000561512641706002016253 00000000000000/* * Copyright (C) 2010-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INFO_H_ #define INFO_H_ #include #include "vigra/imageinfo.hxx" struct LayerInfo { LayerInfo(int a_width, int a_height, bool is_color_image, vigra::ImageImportInfo::PixelType a_pixel_type, vigra::Diff2D a_position, float an_x_resolution, float a_y_resolution) : width(a_width), height(a_height), is_color(is_color_image), pixel_type(a_pixel_type), position(a_position), x_resolution(an_x_resolution), y_resolution(a_y_resolution) {} int width; int height; bool is_color; vigra::ImageImportInfo::PixelType pixel_type; vigra::Diff2D position; float x_resolution; float y_resolution; vigra::Size2D size() const; bool is_float() const; bool is_signed() const; std::pair resolution() const; }; class ImageInfo { typedef std::vector layer_list; public: ImageInfo(const std::string& a_filename) : filename_(a_filename) {} const std::string& filename() const {return filename_;} const LayerInfo* layer(unsigned a_layer_index) const {return &layers_[a_layer_index];} void append(const LayerInfo& an_info) {layers_.push_back(an_info);} unsigned number_of_layers() const {return static_cast(layers_.size());} private: /* const */ std::string filename_; // const time_t filetime_; layer_list layers_; }; class ImageListInformation { typedef std::vector image_list; public: ImageListInformation() {} ImageListInformation(const ImageListInformation* an_image_list); virtual ~ImageListInformation() {} void append(const ImageInfo& an_info) {images_.push_back(an_info);} unsigned number_of_images() const {return static_cast(images_.size());} const ImageInfo* image_info_on(const std::string& a_filename) const; const LayerInfo* layer_info_on(const std::string& a_filename, unsigned a_layer_index) const; private: image_list::const_iterator find_image_by_name(const std::string& a_filename) const; image_list images_; }; #endif // INFO_H_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/layer_selection/info.cc0000644000175000017500000000540112641706002016402 00000000000000/* * Copyright (C) 2010-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include // make_pair #include "info.h" vigra::Size2D LayerInfo::size() const { return vigra::Size2D(width, height); } bool LayerInfo::is_float() const { return pixel_type == vigra::ImageImportInfo::FLOAT || pixel_type == vigra::ImageImportInfo::DOUBLE; } bool LayerInfo::is_signed() const { return pixel_type == vigra::ImageImportInfo::INT16 || pixel_type == vigra::ImageImportInfo::INT32; } std::pair LayerInfo::resolution() const { return std::make_pair(x_resolution, y_resolution); } //////////////////////////////////////////////////////////////////////// ImageListInformation::ImageListInformation(const ImageListInformation* an_image_list) { if (an_image_list != nullptr) { std::copy(an_image_list->images_.begin(), an_image_list->images_.end(), back_inserter(images_)); } } ImageListInformation::image_list::const_iterator ImageListInformation::find_image_by_name(const std::string& a_filename) const { return std::find_if(images_.begin(), images_.end(), [&a_filename](const ImageListInformation::image_list::value_type& x) {return x.filename() == a_filename;}); } const ImageInfo* ImageListInformation::image_info_on(const std::string& a_filename) const { image_list::const_iterator image_info = find_image_by_name(a_filename); if (image_info == images_.end()) { return nullptr; } else { return &(*image_info); } } const LayerInfo* ImageListInformation::layer_info_on(const std::string& a_filename, unsigned a_layer_index) const { image_list::const_iterator image_info = find_image_by_name(a_filename); if (image_info == images_.end()) { return nullptr; } else { if (a_layer_index >= image_info->number_of_layers()) { return nullptr; } else { return image_info->layer(a_layer_index); } } } enblend-enfuse-4.2/src/layer_selection/layer_selection.cc0000644000175000017500000000504712641706002020636 00000000000000/* * Copyright (C) 2010-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H #include #endif #include #include "layer_selection.h" #include "selector.h" LayerSelectionHost::LayerSelectionHost() : selector_(nullptr), info_(nullptr), tally_(nullptr) {} LayerSelectionHost::LayerSelectionHost(const LayerSelectionHost& a_selection) : selector_(a_selection.selector_), info_(new ImageListInformation(a_selection.info_)), tally_(new file_tally_t) {} LayerSelectionHost& LayerSelectionHost::operator=(const LayerSelectionHost& a_selection) { if (this != &a_selection) { selector_ = a_selection.selector_; delete info_; info_ = new ImageListInformation(a_selection.info_); delete tally_; tally_ = new file_tally_t; } return *this; } LayerSelectionHost::~LayerSelectionHost() { delete info_; delete tally_; } std::string LayerSelectionHost::name() const { return selector_->name(); } std::string LayerSelectionHost::description() const { return selector_->description(); } selector::Abstract* LayerSelectionHost::get_selector() const { return selector_; } void LayerSelectionHost::set_selector(selector::Abstract* a_selector) { selector_ = a_selector; } bool LayerSelectionHost::accept(const std::string& a_filename, unsigned a_layer_index) { const bool result = selector_->select(const_cast(info_), a_filename, a_layer_index); if (result) { ++(tally_->operator[](a_filename)[a_layer_index - 1U]); } return result; } selector::layer_ordered_list_t LayerSelectionHost::viable_layers(const std::string& a_filename) { return selector_->viable_layers(const_cast(info_), a_filename); } enblend-enfuse-4.2/src/layer_selection/layer_selection.h0000644000175000017500000000654112641706002020500 00000000000000/* * Copyright (C) 2010-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef LAYER_SELECTION_H_ #define LAYER_SELECTION_H_ #include #include #include #include #include #include "info.h" namespace selector { typedef std::vector layer_ordered_list_t; struct Abstract; // forward declaration for class in "selector.h" } class LayerSelectionHost { typedef std::vector layer_tally_t; typedef std::map file_tally_t; public: LayerSelectionHost(); LayerSelectionHost(const LayerSelectionHost& a_selection); LayerSelectionHost& operator=(const LayerSelectionHost& a_selection); virtual ~LayerSelectionHost(); std::string name() const; std::string description() const; selector::Abstract* get_selector() const; void set_selector(selector::Abstract* a_selector); template void retrieve_image_information(const_iterator begin, const_iterator end) { delete info_; info_ = new ImageListInformation; delete tally_; tally_ = new file_tally_t; for (const_iterator image = begin; image != end; ++image) { ImageInfo image_info((*image)->filename()); vigra::ImageImportInfo file_info((*image)->filename().c_str()); for (int layer = 0; layer < file_info.numImages(); ++layer) { std::unique_ptr layer_info(new vigra::ImageImportInfo(file_info)); layer_info->setImageIndex(layer); image_info.append(LayerInfo(layer_info->width(), layer_info->height(), layer_info->isColor(), layer_info->pixelType(), layer_info->getPosition(), layer_info->getXResolution(), layer_info->getYResolution())); } info_->append(image_info); tally_->insert(file_tally_t::value_type((*image)->filename(), layer_tally_t(file_info.numImages()))); } } virtual bool accept(const std::string& a_filename, unsigned a_layer_index); virtual selector::layer_ordered_list_t viable_layers(const std::string& a_filename); // query tally // std::vector unused_files() const; // std::pair multiply_used_layers() const; private: selector::Abstract* selector_; ImageListInformation* info_; file_tally_t* tally_; }; #endif // LAYER_SELECTION_H_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/self_test.cc0000644000175000017500000003007612641706002014264 00000000000000/* * Copyright (C) 2009-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // No test, no bug. -- Chris Spiel #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include // fabsf #include #include #include "self_test.h" #define lengthof(m_array) (sizeof(m_array) / sizeof(m_array[0])) extern const std::string command; //////////////////////////////////////////////////////////////////////// // Number of arguments we pass to getopt_long in each of our tests. #define ARG_COUNT 4 enum {a_short, b_short, c_short, a_long, b_long, c_long, FLAG_COUNT}; struct test_case { const char* arguments[ARG_COUNT]; int flags[FLAG_COUNT]; }; inline static int int_of_string(const char* s) { return static_cast(strtol(s, nullptr, 10)); } static void reset_getopt_globals() { opterr = 0; // silence getopt_long(3) optopt = -1; // reset "unknown option" character optind = 1; // reset parsing index optarg = nullptr; // reset pointer to value of option argument } static int try_out_getopt_long(int arg_count, const char* arguments[], int* flags) { const char* short_options = "ab:c::"; const struct option long_options[] = { {"long-a", no_argument, nullptr, 1}, {"long-b", required_argument, nullptr, 2}, {"long-c", optional_argument, nullptr, 3}, {nullptr, 0, nullptr, 0} }; reset_getopt_globals(); while (true) { int option_index = 0; int code = getopt_long(arg_count, const_cast(arguments), short_options, long_options, &option_index); if (code == -1) { break; } switch (code) { case 1: flags[a_long] = 1; break; case 2: flags[b_long] = int_of_string(optarg); break; case 3: flags[c_long] = optarg == nullptr ? 1 : int_of_string(optarg); break; case 'a': flags[a_short] = 1; break; case 'b': flags[b_short] = int_of_string(optarg); break; case 'c': flags[c_short] = optarg == nullptr ? 1 : int_of_string(optarg); break; default: return -1; } } return optind; } // Write a list of elements separated by spaces to stream out. template static void write_list(std::ostream& out, unsigned size, const T list) { for (unsigned i = 0U; i != size; ++i) { out << list[i]; if (i != size - 1U) { out << ' '; } } } // Name of the first argument, i.e. the first non-option in the list // of arguments. We need to know its name so that we can check // whether getopt_long(3) really parsed all options. #define ARG1 "1" // Test whether the library function getopt_long(3) works as required. bool getopt_long_works_ok() { bool has_passed_test = true; struct test_case tests[] = { {{"p", ARG1, "2", "3"}, {0, 0, 0, 0, 0, 0}}, {{"p", "-a", ARG1, "2"}, {1, 0, 0, 0, 0, 0}}, {{"p", "-b2", ARG1, "2"}, {0, 2, 0, 0, 0, 0}}, {{"p", "-c", ARG1, "2"}, {0, 0, 1, 0, 0, 0}}, {{"p", "-c2", ARG1, "2"}, {0, 0, 2, 0, 0, 0}}, {{"p", "--long-a", ARG1, "2"}, {0, 0, 0, 1, 0, 0}}, {{"p", "--long-b=2", ARG1, "2"}, {0, 0, 0, 0, 2, 0}}, {{"p", "--long-c", ARG1, "2"}, {0, 0, 0, 0, 0, 1}}, {{"p", "--long-c=2", ARG1, "2"}, {0, 0, 0, 0, 0, 2}}, {{"p", "-a", "-b2", ARG1}, {1, 2, 0, 0, 0, 0}}, {{"p", "-a", "-b2", ARG1}, {1, 2, 0, 0, 0, 0}}, {{"p", "-ab2", "-c", ARG1}, {1, 2, 1, 0, 0, 0}}, {{"p", "-ab2", "-c3", ARG1}, {1, 2, 3, 0, 0, 0}}, {{"p", "--long-a", "--long-b=2", ARG1}, {0, 0, 0, 1, 2, 0}}, {{"p", "--long-a", "--long-b=2", ARG1}, {0, 0, 0, 1, 2, 0}}, {{"p", "--long-b=2", "--long-c", ARG1}, {0, 0, 0, 0, 2, 1}}, {{"p", "--long-b=2", "--long-c=3", ARG1}, {0, 0, 0, 0, 2, 3}}, {{"p", "-a", "--long-a", ARG1}, {1, 0, 0, 1, 0, 0}}, {{"p", "-b2", "--long-a", ARG1}, {0, 2, 0, 1, 0, 0}}, {{"p", "-a", "--long-b=2", ARG1}, {1, 0, 0, 0, 2, 0}}, {{"p", "-b2", "--long-b=2", ARG1}, {0, 2, 0, 0, 2, 0}}, {{nullptr, nullptr, nullptr}, {0, 0, 0, 0, 0, 0}} }; const unsigned arg_count = lengthof(tests->arguments); const unsigned flag_count = lengthof(tests->flags); for (struct test_case* t = tests; t->arguments[0] != nullptr; ++t) { int flags[] = {0, 0, 0, 0, 0, 0}; assert(lengthof(tests->flags) == lengthof(flags)); const int index = try_out_getopt_long(arg_count, t->arguments, flags); if (index < 0 || index >= static_cast(arg_count) || strcmp(t->arguments[index], ARG1) != 0) { std::cerr << command << ": failed self test: getopt_long(3) did not parse argument list \""; write_list(std::cerr, arg_count, t->arguments); std::cerr << "\"\n"; has_passed_test = false; } for (unsigned i = 0U; i != flag_count; ++i) { if (flags[i] != t->flags[i]) { std::cerr << command << ": failed self test: getopt_long(3) incorrectly parses argument list \""; write_list(std::cerr, arg_count, t->arguments); std::cerr << "\";\n"; std::cerr << command << ": failed self test: expected {"; write_list(std::cerr, flag_count, t->flags); std::cerr << "}, but got {"; write_list(std::cerr, flag_count, flags); std::cerr << "}\n"; has_passed_test = false; } } } reset_getopt_globals(); return has_passed_test; } // Run a kernel, if we have OpenCL support. #ifdef OPENCL typedef std::vector float_vector; static const std::string axpy_source("kernel void\n" "axpy(const float alpha,\n" " global const float *restrict x,\n" " global const float *restrict y,\n" " const int n,\n" " global float *restrict z)\n" "{\n" " const int i = get_global_id(0);\n" "\n" " if (i >= n)\n" " {\n" " return;\n" " }\n" "\n" " z[i] = alpha * x[i] + y[i];\n" "}\n"); class Alpha_times_x_plus_y : public ocl::BuildableFunction { public: Alpha_times_x_plus_y() = delete; explicit Alpha_times_x_plus_y(const cl::Context& a_context) : f_(a_context, axpy_source) {} void build(const std::string& a_build_option) { std::cerr << "\n+ Alpha_times_x_plus_y::build: by request\n\n"; f_.build(a_build_option); std::cerr << "+ Alpha_times_x_plus_y::build: log begin ================\n" << f_.build_log() << "\n+ Alpha_times_x_plus_y::build: log end ================\n"; } void wait() { f_.wait(); std::cerr << "\n+ Alpha_times_x_plus_y::wait: carry on...\n\n"; initialize(); } void run(float alpha, const float_vector& x, const float_vector& y, float_vector& z) { const size_t n = x.size(); assert(n == y.size()); assert(n <= z.size()); const size_t buffer_size = n * sizeof(float); cl::Buffer x_buffer(f_.context(), CL_MEM_READ_ONLY, buffer_size); cl::Buffer y_buffer(f_.context(), CL_MEM_READ_ONLY, buffer_size); cl::Buffer z_buffer(f_.context(), CL_MEM_WRITE_ONLY, buffer_size); kernel_.setArg(0U, static_cast(alpha)); kernel_.setArg(1U, x_buffer); kernel_.setArg(2U, y_buffer); kernel_.setArg(3U, static_cast(n)); kernel_.setArg(4U, z_buffer); f_.queue().enqueueWriteBuffer(x_buffer, CL_TRUE, 0U, buffer_size, &x[0]); f_.queue().enqueueWriteBuffer(y_buffer, CL_TRUE, 0U, buffer_size, &y[0]); f_.queue().enqueueNDRangeKernel(kernel_, cl::NullRange, cl::NDRange(n), cl::NullRange); f_.queue().enqueueReadBuffer(z_buffer, CL_TRUE, 0U, buffer_size, &z[0]); } private: void initialize() { kernel_ = f_.create_kernel("axpy"); } ocl::LazyFunctionCXXOfString f_; cl::Kernel kernel_; }; // Alpha_times_x_plus_y static void alpha_times_x_plus_y(float alpha, const float_vector& x, const float_vector& y, float_vector& z) { const size_t n = x.size(); assert(n == y.size()); assert(n <= z.size()); for (size_t i = 0U; i != n; ++i) { z[i] = alpha * x[i] + y[i]; } } template inline static void iota(forward_iterator first, forward_iterator last, t a_value) { while (first != last) { *first++ = a_value++; } } static bool test_axpy_on_gpu(cl::Context* a_context) { const float alpha = 2.5F; const size_t n = 20U; float_vector x(n); float_vector y(n); float_vector z0(n); float_vector z(n); iota(x.begin(), x.end(), 1.0F); iota(y.begin(), y.end(), 1.0F); alpha_times_x_plus_y(alpha, x, y, z0); try { Alpha_times_x_plus_y axpy(*a_context); axpy.build("-Werror"); axpy.wait(); axpy.run(alpha, x, y, z); } catch (cl::Error& a_cl_error) { std::cerr << command << ": warning: plain cl error: " << a_cl_error.what() << "\n" << command << ": note: " << ocl::string_of_error_code(a_cl_error.err()) << std::endl; return false; } catch (ocl::runtime_error& an_opencl_runtime_error) { std::cerr << command << ": warning: ocl error: " << an_opencl_runtime_error.what() << "\n" << command << ": note: " << ocl::string_of_error_code(an_opencl_runtime_error.error().err()) << "\n" << command << ": note: " << an_opencl_runtime_error.additional_message() << std::endl; return false; } catch (...) { std::cerr << command << ": warning: unknown exception thrown during self test \"test_axpy_on_gpu\"" << std::endl; return false; } for (size_t i = 0U; i != n; ++i) { #ifdef DEBUG std::cout << "+ test_axpy_on_gpu: [" << i << "] " << alpha << " * " << x[i] << " + " << y[i] << " = " << z[i] << " (reference: " << z0[i] << "), " << "delta: " << std::scientific << fabsf(z[i] - z0[i]) << std::fixed << "\n"; #endif // DEBUG if (fabsf(z[i] - z0[i]) > std::numeric_limits::epsilon()) { std::cerr << "+ test_axpy_on_gpu: failure at index " << i << ", expected " << z0[i] << ", but got " << z[i] << "\n"; return false; } } return true; } bool gpu_is_ok(cl::Context* a_context) { return test_axpy_on_gpu(a_context); } #endif // OPENCL enblend-enfuse-4.2/src/self_test.h0000644000175000017500000000200712641706002014117 00000000000000/* * Copyright (C) 2009-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SELF_TEST_H #define SELF_TEST_H #include "opencl.h" #ifdef OPENCL extern bool gpu_is_ok(cl::Context* a_context); #endif extern bool getopt_long_works_ok(); #endif /* SELF_TEST_H */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/introspection.h0000644000175000017500000000222312641706002015027 00000000000000/* * Copyright (C) 2015, 2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INTROSPECTION_H_INCLUDED_ #define INTROSPECTION_H_INCLUDED_ namespace introspection { void printVersion(int argc, char** argv); void printImageFormats(); void printSignature(); void printGlobbingAlgos(); void printSoftwareComponents(); } // end namespace introspection #endif // INTROSPECTION_H_INCLUDED_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/exposure_weight.cc0000644000175000017500000002250512641706002015513 00000000000000/* * Copyright (C) 2015, 2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "global.h" #include "openmp_def.h" // omp::atomic_t #include "dynamic_loader.h" // HAVE_DYNAMICLOADER_IMPL #include "opencl.h" // macro OPENCL #include "opencl_exposure_weight.h" #include "exposure_weight.h" extern const std::string command; extern ExposureWeight* ExposureWeightFunction; namespace exposure_weight { #ifdef HAVE_DYNAMICLOADER_IMPL class DynamicExposureWeight : public ExposureWeight { public: DynamicExposureWeight() = delete; DynamicExposureWeight(const std::string& library_name, const std::string& symbol_name, double y_optimum = 0.5, double width = 0.2) : ExposureWeight(y_optimum, width), library_(library_name), symbol_(symbol_name), dynamic_loader_(DynamicLoader(library_name)), function_(dynamic_loader_.resolve(symbol_name)) { assert(function_); if (function_->interface_version() != EXPOSURE_WEIGHT_INTERFACE_VERSION) { std::cerr << command << ": user-defined weight function \"" << symbol_name << "\"\n" << command << ": defined in shared object \"" << library_name << "\"\n" << command << ": matches interface version " << function_->interface_version() << ", but " << command << " requires version " << EXPOSURE_WEIGHT_INTERFACE_VERSION << std::endl; exit(1); } } void initialize(double y_optimum, double width_parameter, ExposureWeight::argument_const_iterator user_arguments_begin, ExposureWeight::argument_const_iterator user_arguments_end) override { #ifdef DEBUG std::cout << "+ DynamicExposureWeight::initialize\n"; std::for_each(user_arguments_begin, user_arguments_end, [](const std::string& x) {std::cout << "+ DynamicExposureWeight::initialize: <" << x << ">\n";}); #endif function_->initialize(y_optimum, width_parameter, user_arguments_begin, user_arguments_end); } double weight(double y) override {return function_->weight(y);} private: std::string library_; std::string symbol_; DynamicLoader dynamic_loader_; ExposureWeight* function_; }; static ExposureWeight* make_dynamic_weight_function(const std::string& name, ExposureWeight::argument_const_iterator arguments_begin, ExposureWeight::argument_const_iterator arguments_end, double y_optimum, double width) { if (arguments_begin == arguments_end) { // Remember that built-in exposure-weight functions never // take any arguments. std::cerr << command << ": unknown built-in exposure weight function \"" << name << "\"" << std::endl; exit(1); } else { const std::string symbol_name = *arguments_begin; ExposureWeight* weight_object; try { weight_object = new DynamicExposureWeight(name, symbol_name); weight_object->initialize(y_optimum, width, std::next(arguments_begin), arguments_end); } catch (ExposureWeight::error& exception) { std::cerr << command << ": user-defined weight function \"" << symbol_name << "\"\n" << command << ": defined in shared object \"" << name << "\"\n" << command << ": raised exception: " << exception.what() << std::endl; exit(1); } return weight_object; } } #endif // HAVE_DYNAMICLOADER_IMPL ExposureWeight* make_weight_function(const std::string& name, ExposureWeight::argument_const_iterator arguments_begin, ExposureWeight::argument_const_iterator arguments_end, double y_optimum, double width) { delete ExposureWeightFunction; std::string possible_built_in(name); enblend::to_lower(possible_built_in); if (possible_built_in == "gauss" || possible_built_in == "gaussian") { return new Gaussian(y_optimum, width); } else if (possible_built_in == "lorentz" || possible_built_in == "lorentzian") { return new Lorentzian(y_optimum, width); } else if (possible_built_in == "halfsine" || possible_built_in == "half-sine") { return new HalfSinusodial(y_optimum, width); } else if (possible_built_in == "fullsine" || possible_built_in == "full-sine") { return new FullSinusodial(y_optimum, width); } else if (possible_built_in == "bisquare" || possible_built_in == "bi-square") { return new Bisquare(y_optimum, width); } else { #if defined(HAVE_DYNAMICLOADER_IMPL) && defined(OPENCL) #ifdef DEBUG std::cerr << "+ make_weight_function: HAVE_DYNAMICLOADER_IMPL && OPENCL" << std::endl; #endif if (opencl_exposure_weight::is_opencl_file(name)) { return opencl_exposure_weight::make_weight_function(name, arguments_begin, arguments_end, y_optimum, width); } else { return make_dynamic_weight_function(name, arguments_begin, arguments_end, y_optimum, width); } #elif defined(OPENCL) #ifdef DEBUG std::cerr << "+ make_weight_function: OPENCL only" << std::endl; #endif if (opencl_exposure_weight::is_opencl_file(name)) { return opencl_exposure_weight::make_weight_function(name, arguments_begin, arguments_end, y_optimum, width); } else { std::cerr << command << ": OpenCL source file required" << << std::endl; exit(1); } #elif defined(HAVE_DYNAMICLOADER_IMPL) #ifdef DEBUG std::cerr << "+ make_weight_function: HAVE_DYNAMICLOADER_IMPL only" << std::endl; #endif if (opencl_exposure_weight::is_opencl_file(name)) { std::cerr << command << ": shared-object file (aka dynamic library) required" << std::endl; exit(1); } else { return make_dynamic_weight_function(name, arguments_begin, arguments_end, y_optimum, width); } #else std::cerr << command << ": unknown built-in exposure weight function \"" << name << "\"\n" << command << ": note: this binary has no support for dynamic loading of\n" << command << ": note: exposure weight functions" << std::endl; exit(1); #endif } } void dump_weight_function(ExposureWeight* weight_function, int n) { assert(n >= 2); for (int i = 0; i < n; ++i) { const double x = static_cast(i) / static_cast(n - 1); const double w = weight_function->weight(x); std::cout << i << ' ' << x << ' ' << w << '\n'; } } weight_function_check_t check_weight_function(ExposureWeight* weight_function, int n) { assert(n >= 2); int zero_count = 0; for (int i = 0; i < n; ++i) { const double y = static_cast(i) / static_cast(n - 1); const double w = weight_function->weight(y); if (w < 0.0) { return NEGATIVE; } else if (w > 1.0) { return NON_UNIT; } if (w >= 0.0 && w <= std::numeric_limits::denorm_min()) { ++zero_count; } } return zero_count == n ? DEGENERATE : OK; } } // namespace exposure_weight enblend-enfuse-4.2/src/global.h0000644000175000017500000001174212665527175013417 00000000000000/* * Copyright (C) 2009-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __GLOBAL_H__ #define __GLOBAL_H__ // Here we define macros and types that we already need in the // definitions of global variables. #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #ifdef HAVE_UNORDERED_MAP #include #else #include #endif #include // Defines to control how many -v flags are required for each type // of message to be produced on stdout. #define VERBOSE_ASSEMBLE_MESSAGES 1 #define VERBOSE_CHECKPOINTING_MESSAGES 1 #define VERBOSE_OPENCL_MESSAGES 1 // ANTICIPATED CHANGE: raise level when we are done with debugging #define VERBOSE_BLEND_MESSAGES 2 #define VERBOSE_MASK_MESSAGES 2 #define VERBOSE_NFT_MESSAGES 2 #define VERBOSE_PYRAMID_MESSAGES 2 #define VERBOSE_SIGNATURE_REPORTING 2 #define VERBOSE_TIFF_MESSAGES 2 #define VERBOSE_VERSION_REPORTING 2 #define VERBOSE_COLOR_CONVERSION_MESSAGES 3 #define VERBOSE_DIFFERENCE_STATISTICS 3 #define VERBOSE_LAYER_SELECTION 3 #define VERBOSE_RESPONSE_FILES 3 #define VERBOSE_ABB_MESSAGES 4 #define VERBOSE_IBB_MESSAGES 4 #define VERBOSE_INPUT_IMAGE_INFO_MESSAGES 4 #define VERBOSE_INPUT_UNION_SIZE_MESSAGES 4 #define VERBOSE_ROIBB_SIZE_MESSAGES 4 #define VERBOSE_UBB_MESSAGES 4 #define VERBOSE_CFI_MESSAGES 5 #define VERBOSE_GDA_MESSAGES 5 #define VERBOSE_MEMORY_ESTIMATION_MESSAGES 6 //< default-output-filename a.tif #define DEFAULT_OUTPUT_FILENAME "a.tif" namespace enblend { inline static void to_lower(std::string& a_string) { for (auto& c : a_string) { c = std::tolower(c, std::locale()); } } inline static void to_upper(std::string& a_string) { for (auto& c : a_string) { c = std::toupper(c, std::locale()); } } inline static std::string to_lower_copy(const std::string& a_string) { std::string result; std::for_each(a_string.begin(), a_string.end(), [&](char c) {result.push_back(std::tolower(c, std::locale()));}); return result; } inline static std::string to_upper_copy(const std::string& a_string) { std::string result; std::for_each(a_string.begin(), a_string.end(), [&](char c) {result.push_back(std::toupper(c, std::locale()));}); return result; } inline static void trim(std::string& a_string) { const size_t start = a_string.find_first_not_of(" \t\n\r"); const size_t end = a_string.find_last_not_of(" \t\n\r"); a_string.assign(a_string, start, 1U + end - start); } } // end namespace enblend /** The different kinds of boundary conditions we can impose upon an * image. */ typedef enum BoundaryKind { UnknownWrapAround, // unknown kind OpenBoundaries, // contractible HorizontalStrip, // contractible along 2nd axis VerticalStrip, // contractible along 1st axis DoubleStrip // non-contractible } boundary_t; enum MainAlgo { NFT, GraphCut }; // Colorspaces available for pyramidal blending operations typedef enum { UndeterminedColorspace, // explicit `not-a-colorspace' value IdentitySpace, // (1d) luminance interval for grayscale images and (3d) RGB-cube for RGB-images CIELAB, CIELUV, CIECAM } blend_colorspace_t; //< default-tiff-resolution 300 #define DEFAULT_TIFF_RESOLUTION 300.0f // units are dots-per-inch ("DPI") struct TiffResolution { TiffResolution() : x(0.0f), y(0.0f) {} TiffResolution(float anXresolution, float aYresolution) : x(anXresolution), y(aYresolution) {} bool operator==(const TiffResolution& anOther) const { return this->x == anOther.x && this->y == anOther.y; } bool operator!=(const TiffResolution& anOther) const { return !operator==(anOther); } float x; float y; }; #endif /* __GLOBAL_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/enfuse.10000644000175000017500000001715612676432657013364 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.4. .TH ENFUSE "1" "March 2016" "enfuse 4.2" "User Commands" .SH NAME enfuse \- manual page for enfuse 4.2 .SH SYNOPSIS .B enfuse [\fI\,options\/\fR] [\fI\,--output=IMAGE\/\fR] \fI\,INPUT\/\fR... .SH DESCRIPTION Fuse INPUT images into a single IMAGE. .PP INPUT... are image filenames or response filenames. Response filenames start with an "@" character. .SH OPTIONS .SS "Common options:" .TP \fB\-l\fR, \fB\-\-levels\fR=\fI\,LEVELS\/\fR limit number of blending LEVELS to use (1 to 29); negative number of LEVELS decreases maximum; "auto" restores the default automatic maximization .TP \fB\-o\fR, \fB\-\-output\fR=\fI\,FILE\/\fR write output to FILE; default: "a.tif" .TP \fB\-v\fR, \fB\-\-verbose\fR[=\fI\,LEVEL\/\fR] verbosely report progress; repeat to increase verbosity or directly set to LEVEL .TP \fB\-\-compression\fR=\fI\,COMPRESSION\/\fR set compression of output image to COMPRESSION, where COMPRESSION is: "deflate", "jpeg", "lzw", "none", "packbits", for TIFF files and 0 to 100, or "jpeg", "jpeg\-arith" for JPEG files, where "jpeg" and "jpeg\-arith" accept a compression level .SS "Advanced options:" .TP \fB\-\-blend\-colorspace\fR=\fI\,COLORSPACE\/\fR force COLORSPACE for blending operations; Enfuse uses "CIELUV" for images with ICC\-profile and "IDENTITY" for those without and also for all floating\-point images; other available blend color spaces are "CIELAB" and "CIECAM" .TP \fB\-c\fR, \fB\-\-ciecam\fR use CIECAM02 to blend colors; disable with "\-\-no\-ciecam"; note that this option will be withdrawn in favor of "\-\-blend\-colorspace" .TP \fB\-d\fR, \fB\-\-depth\fR=\fI\,DEPTH\/\fR set the number of bits per channel of the output image, where DEPTH is "8", "16", "32", "r32", or "r64" .TP \fB\-f\fR WIDTHxHEIGHT[+xXOFFSET+yYOFFSET] manually set the size and position of the output image; useful for cropped and shifted input TIFF images, such as those produced by Nona .TP \fB\-g\fR associated\-alpha hack for Gimp (before version 2) and Cinepaint .TP \fB\-w\fR, \fB\-\-wrap\fR[=\fI\,MODE\/\fR] wrap around image boundary, where MODE is "none", "horizontal", "vertical", or "both"; default: none; without argument the option selects horizontal wrapping .SS "Fusion options:" .TP \fB\-\-exposure\-weight\fR=\fI\,WEIGHT\/\fR weight given to well\-exposed pixels (0 <= WEIGHT <= 1); default: 1 .TP \fB\-\-saturation\-weight\fR=\fI\,WEIGHT\/\fR weight given to highly\-saturated pixels (0 <= WEIGHT <= 1); default: 0.2 .TP \fB\-\-contrast\-weight\fR=\fI\,WEIGHT\/\fR weight given to pixels in high\-contrast neighborhoods (0 <= WEIGHT <= 1); default: 0 .TP \fB\-\-entropy\-weight\fR=\fI\,WEIGHT\/\fR weight given to pixels in high entropy neighborhoods (0 <= WEIGHT <= 1); default: 0 .TP \fB\-\-exposure\-optimum\fR=\fI\,OPTIMUM\/\fR optimum exposure value, usually the maximum of the weighting function (0 <= OPTIMUM <= 1); default: 0.5 .TP \fB\-\-exposure\-width\fR=\fI\,WIDTH\/\fR characteristic width of the weighting function (WIDTH > 0); default: 0.2 .TP \fB\-\-soft\-mask\fR average over all masks; this is the default .TP \fB\-\-hard\-mask\fR force hard blend masks and no averaging on finest scale; this is especially useful for focus stacks with thin and high contrast features, but leads to increased noise .SS "Expert options:" .TP \fB\-\-save\-masks[\fR=\fI\,SOFT\-TEMPLATE[\/\fR:HARD\-TEMPLATE]] save weight masks in SOFT\-TEMPLATE and HARD\-TEMPLATE; conversion chars: "%i": mask index, "%n": mask number, "%p": full path, "%d": dirname, "%b": basename, "%f": filename, "%e": extension; lowercase characters refer to input images uppercase to the output image default: "softmask\-%n.tif":"hardmask\-%n.tif" .TP \fB\-\-load\-masks[\fR=\fI\,SOFT\-TEMPLATE[\/\fR:HARD\-TEMPLATE]] skip calculation of weight maps and use the ones in the files matching the templates instead. These can be either hard or soft masks. For template syntax see "\-\-save\-masks"; default: "softmask\-%n.tif":"hardmask\-%n.tif" .TP \fB\-\-fallback\-profile\fR=\fI\,PROFILE\-FILE\/\fR use the ICC profile from PROFILE\-FILE instead of sRGB .TP \fB\-\-layer\-selector\fR=\fI\,ALGORITHM\/\fR set the layer selector ALGORITHM; default: "all\-layers"; available algorithms are: "all\-layers": select all layers in any image; "first\-layer": select only first layer in each (multi\-)layer image; "last\-layer": select only last layer in each (multi\-)layer image; "largest\-layer": select largest layer in each (multi\-)layer image; "no\-layer": do not select any layer from any image; .TP \fB\-\-parameter\fR=\fI\,KEY1[=VALUE1][\/\fR:KEY2[=VALUE2][:...]] set one or more KEY\-VALUE pairs .SS "Expert fusion options:" .TP \fB\-\-exposure\-weight\-function\fR=\fI\,WEIGHT\-FUNCTION\/\fR (1st form) select one of the built\-in exposure WEIGHT\-FUNCTIONs: "gaussian", "lorentzian", "half\-sine", "full\-sine", or "bi\-square"; default: "gaussian" .TP \fB\-\-exposure\-weight\-function\fR=\fI\,SHARED\-OBJECT\/\fR:SYMBOL[:ARGUMENT[:...]] (2nd form) load user\-defined exposure weight function SYMBOL from SHARED\-OBJECT and optionally pass ARGUMENTs .TP \fB\-\-exposure\-cutoff\fR=\fI\,LOWERCUTOFF[\/\fR:UPPERCUTOFF[:LOWERPROJECTOR[:UPPERPROJECTOR]]] LOWERCUTOFF and UPPERCUTOFF are the values below or above of which pixels are weighted with zero weight in exposure weighting; append "%" signs for relative values; default: 0%:100%:anti\-value:value .TP \fB\-\-contrast\-window\-size\fR=\fI\,SIZE\/\fR set window SIZE for local\-contrast analysis (SIZE >= 3); default: 5 .TP \fB\-\-contrast\-edge\-scale\fR=\fI\,EDGESCALE[\/\fR:LCESCALE[:LCEFACTOR]] set scale on which to look for edges; positive LCESCALE switches on local contrast enhancement by LCEFACTOR (EDGESCALE, LCESCALE, LCEFACTOR >= 0); append "%" to LCESCALE for values relative to EDGESCALE; append "%" to LCEFACTOR for relative value; default: 0:0:0 .TP \fB\-\-contrast\-min\-curvature\fR=\fI\,CURVATURE\/\fR minimum CURVATURE for an edge to qualify; append "%" for relative values; default: 0 .TP \fB\-\-gray\-projector\fR=\fI\,PROJECTOR\/\fR apply gray\-scale PROJECTOR in exposure or contrast weighing, where PROJECTOR is one of "anti\-value", "average", "l\-star", "lightness", "luminance", "pl\-star", "value", or "channel\-mixer:RED\-WEIGHT:GREEN\-WEIGHT:BLUE\-WEIGHT"; default: "average" .TP \fB\-\-entropy\-window\-size\fR=\fI\,SIZE\/\fR set window SIZE for local entropy analysis (SIZE >= 3); default: 3 .TP \fB\-\-entropy\-cutoff\fR=\fI\,LOWERCUTOFF[\/\fR:UPPERCUTOFF] LOWERCUTOFF is the value below of which pixels are treated as black and UPPERCUTOFF is the value above of which pixels are treated as white in the entropy weighting; append "%" signs for relative values; default: 0%:100% .SS "Information options:" .TP \fB\-h\fR, \fB\-\-help\fR print this help message and exit .TP \fB\-V\fR, \fB\-\-version\fR output version information and exit .TP \fB\-\-show\-globbing\-algorithms\fR show all globbing algorithms .TP \fB\-\-show\-image\-formats\fR show all recognized image formats and their filename extensions .TP \fB\-\-show\-signature\fR show who compiled the binary when and on which machine .TP \fB\-\-show\-software\-components\fR show the software components with which Enfuse was compiled .PP Enfuse accepts arguments to any option in uppercase as well as in lowercase letters. .SH AUTHOR Written by Andrew Mihal, Christoph Spiel and others. .SH "REPORTING BUGS" Report bugs at . .SH COPYRIGHT Copyright \(co 2004\-2009 Andrew Mihal. .br Copyright \(co 2009\-2016 Christoph Spiel. .PP License GPLv2+: GNU GPL version 2 or later .br This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. enblend-enfuse-4.2/src/enfuse.h0000644000175000017500000017761612670235416013447 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ENFUSE_H__ #define __ENFUSE_H__ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "common.h" #include "filespec.h" #include "opencl.h" #include "openmp_def.h" #include "openmp_vigra.h" #include "numerictraits.h" #include "fixmath.h" #include "assemble.h" #include "blend.h" #include "bounds.h" #include "pyramid.h" #include "mga.h" using vigra::functor::Arg1; using vigra::functor::Arg2; using vigra::functor::Param; namespace enblend { // Keep sum and sum-of-squares together for improved CPU-cache locality. template struct ScratchPad { ScratchPad() : sum(T()), sumSqr(T()), n(size_t()) {} T sum; T sumSqr; size_t n; }; template void localStdDevIf(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc, MaskIterator mask_ul, MaskAccessor mask_acc, DestIterator dest_ul, DestAccessor dest_acc, vigra::Size2D size) { typedef typename vigra::NumericTraits::RealPromote SrcSumType; typedef vigra::NumericTraits DestTraits; typedef ScratchPad ScratchPadType; typedef std::vector ScratchPadArray; typedef typename ScratchPadArray::iterator ScratchPadArrayIterator; vigra_precondition(size.x > 1 && size.y > 1, "localStdDevIf(): window for local variance must be at least 2x2"); vigra_precondition(src_lr.x - src_ul.x >= size.x && src_lr.y - src_ul.y >= size.y, "localStdDevIf(): window larger than image"); const typename SrcIterator::difference_type imageSize = src_lr - src_ul; ScratchPadArray scratchPad(imageSize.x + 1); const vigra::Diff2D border(size.x / 2, size.y / 2); const vigra::Diff2D nextUpperRight(size.x / 2 + 1, -size.y / 2); SrcIterator const srcEnd(src_lr - border); SrcIterator const srcEndXm1(srcEnd - vigra::Diff2D(1, 0)); // For each row in the source image... #ifdef OPENMP #pragma omp parallel for firstprivate (scratchPad) #endif for (int row = 0; row < imageSize.y - 2 * border.y; ++row) { SrcIterator srcRow(src_ul + border + vigra::Diff2D(0, row)); MaskIterator maskRow(mask_ul + border + vigra::Diff2D(0, row)); DestIterator destRow(dest_ul + border + vigra::Diff2D(0, row)); // Row's running values SrcSumType sum = vigra::NumericTraits::zero(); SrcSumType sumSqr = vigra::NumericTraits::zero(); size_t n = 0; SrcIterator const windowSrcUpperLeft(srcRow - border); SrcIterator const windowSrcLowerRight(srcRow + border); SrcIterator windowSrc; MaskIterator const windowMaskUpperLeft(maskRow - border); MaskIterator windowMask; ScratchPadArrayIterator spCol; // Initialize running-sums of this row for (windowSrc = windowSrcUpperLeft, windowMask = windowMaskUpperLeft, spCol = scratchPad.begin(); windowSrc.x <= windowSrcLowerRight.x; ++windowSrc.x, ++windowMask.x, ++spCol) { SrcSumType sumInit = vigra::NumericTraits::zero(); SrcSumType sumSqrInit = vigra::NumericTraits::zero(); size_t nInit = 0; for (windowSrc.y = windowSrcUpperLeft.y, windowMask.y = windowMaskUpperLeft.y; windowSrc.y <= windowSrcLowerRight.y; ++windowSrc.y, ++windowMask.y) { if (mask_acc(windowMask)) { const SrcSumType value = src_acc(windowSrc); sumInit += value; sumSqrInit += square(value); ++nInit; } } // Set scratch pad's column-wise values spCol->sum = sumInit; spCol->sumSqr = sumSqrInit; spCol->n = nInit; // Update totals sum += sumInit; sumSqr += sumSqrInit; n += nInit; } // Write one row of results SrcIterator srcCol(srcRow); MaskIterator maskCol(maskRow); DestIterator destCol(destRow); ScratchPadArrayIterator old(scratchPad.begin()); ScratchPadArrayIterator next(scratchPad.begin() + size.x); while (true) { // Compute standard deviation if (mask_acc(maskCol)) { const SrcSumType result = n <= 1 ? vigra::NumericTraits::zero() : sqrt((sumSqr - square(sum) / n) / (n - 1)); dest_acc.set(DestTraits::fromRealPromote(result), destCol); } if (srcCol.x == srcEndXm1.x) { break; } // Compute auxilliary values of next column SrcSumType sumInit = vigra::NumericTraits::zero(); SrcSumType sumSqrInit = vigra::NumericTraits::zero(); size_t nInit = 0; for (windowSrc = srcCol + nextUpperRight, windowMask = maskCol + nextUpperRight; windowSrc.y <= windowSrcLowerRight.y; ++windowSrc.y, ++windowMask.y) { if (mask_acc(windowMask)) { const SrcSumType value = src_acc(windowSrc); sumInit += value; sumSqrInit += square(value); ++nInit; } } // Set sums of next column next->sum = sumInit; next->sumSqr = sumSqrInit; next->n = nInit; // Update totals sum += sumInit - old->sum; sumSqr += sumSqrInit - old->sumSqr; n += nInit - old->n; // Advance to next column ++srcCol.x; ++maskCol.x; ++destCol.x; ++old; ++next; } } } template class Histogram { enum {GRAY = 0, CHANNELS = 3}; public: typedef vigra::NumericTraits InputPixelTraits; typedef typename InputPixelTraits::ValueType KeyType; // scalar values are our keys typedef typename InputPixelTraits::isScalar pixelIsScalar; typedef unsigned DataType; // pixel counts are our data typedef vigra::NumericTraits ResultPixelTraits; typedef typename ResultPixelTraits::ValueType ResultType; typedef std::map MapType; typedef std::pair PairType; typedef typename MapType::const_iterator MapConstIterator; typedef typename MapType::iterator MapIterator; typedef typename MapType::size_type MapSizeType; Histogram() {clear();} void clear() { for (int channel = 0; channel < CHANNELS; ++channel) { totalCount[channel] = DataType(); histogram[channel].clear(); } } static void setPrecomputedEntropySize(size_t size) { // PERFORMANCE: setPrecomputedEntropySize is a pure // performance enhancer otherwise the function is completely // redundant. It derives its existence from the facts that // computing the entropy "p * log(p)" given the probability // "p" is an expensive operation _and_ most of the time the // moving window is filled completely, i.e., no pixel is // masked. precomputedSize = size; delete [] precomputedLog; delete [] precomputedEntropy; if (size == 0) { precomputedLog = nullptr; precomputedEntropy = nullptr; } else { precomputedLog = new double[size + 1]; vigra_precondition(precomputedLog != nullptr, "Histogram::setPrecomputedSize: failed to allocate log-preevaluate memory"); precomputedEntropy = new double[size + 1]; vigra_precondition(precomputedEntropy != nullptr, "Histogram::setPrecomputedSize: failed to allocate entropy-preevaluate memory"); precomputedLog[0] = 0.0; // just to have a reliable value precomputedEntropy[0] = 0.0; for (size_t i = 1; i <= size; ++i) { const double p = static_cast(i) / static_cast(size); precomputedLog[i] = log(static_cast(i)); precomputedEntropy[i] = p * log(p); } } } Histogram& operator=(const Histogram& other) { if (this != &other) { for (int channel = 0; channel < CHANNELS; ++channel) { totalCount[channel] = other.totalCount[channel]; histogram[channel] = other.histogram[channel]; } } return *this; } void insert(const InputPixelType& x) {insertFun(x, pixelIsScalar());} void insert(const Histogram* other) {insertFun(other, pixelIsScalar());} void erase(const InputPixelType& x) {eraseFun(x, pixelIsScalar());} void erase(const Histogram* other) {eraseFun(other, pixelIsScalar());} ResultPixelType entropy() const {return entropyFun(pixelIsScalar());} protected: void insertInChannel(int channel, const PairType& keyval) { // PERFORMANCE: The actual insertion code below code is a much // faster version of // MapIterator const i = histogram[channel].find(keyval.first); // if (i == histogram[channel].end()) // histogram[channel].insert(keyval); // else i->second += keyval.second; MapIterator const lowerBound = histogram[channel].lower_bound(keyval.first); const DataType count = keyval.second; if (lowerBound != histogram[channel].end() && !(histogram[channel].key_comp()(keyval.first, lowerBound->first))) { lowerBound->second += count; } else { histogram[channel].insert(lowerBound, keyval); } totalCount[channel] += count; } void eraseInChannel(int channel, const PairType& keyval) { MapIterator const i = histogram[channel].find(keyval.first); assert(i != histogram[channel].end()); DataType& c = i->second; const DataType count = keyval.second; if (c > count) { c -= count; } else { // PERFORMANCE: It is _much_ faster to erase unneeded bins // right away than it is e.g. to periodically (think of // every column) cleaning up the whole map while wasting // time in lots of comparisons until then. histogram[channel].erase(i); } totalCount[channel] -= count; } double entropyOfChannel(int channel) const { const DataType total = totalCount[channel]; const MapSizeType actualBins = histogram[channel].size(); if (total == 0 || actualBins <= 1) { return 0.0; } else { double e = 0.0; MapConstIterator const end = histogram[channel].end(); if (total == precomputedSize) { for (MapConstIterator i = histogram[channel].begin(); i != end; ++i) { e += precomputedEntropy[i->second]; } return -e / precomputedLog[actualBins]; } else { for (MapConstIterator i = histogram[channel].begin(); i != end; ++i) { const double p = i->second / static_cast(total); e += p * log(p); } return -e / log(static_cast(actualBins)); } } } // Grayscale void insertFun(const InputPixelType& x, vigra::VigraTrueType) { insertInChannel(GRAY, PairType(x, 1U)); } void insertFun(const Histogram* other, vigra::VigraTrueType) { MapConstIterator const end = other->histogram[GRAY].end(); for (MapConstIterator i = other->histogram[GRAY].begin(); i != end; ++i) { insertInChannel(GRAY, *i); } } void eraseFun(const InputPixelType& x, vigra::VigraTrueType) { eraseInChannel(GRAY, PairType(x, 1U)); } void eraseFun(const Histogram* other, vigra::VigraTrueType) { MapConstIterator const end = other->histogram[GRAY].end(); for (MapConstIterator i = other->histogram[GRAY].begin(); i != end; ++i) { eraseInChannel(GRAY, *i); } } ResultPixelType entropyFun(vigra::VigraTrueType) const { const double max = static_cast(vigra::NumericTraits::max()); return ResultPixelType(ResultPixelTraits::fromRealPromote(entropyOfChannel(GRAY) * max)); } // RGB void insertFun(const InputPixelType& x, vigra::VigraFalseType) { for (int channel = 0; channel < CHANNELS; ++channel) { insertInChannel(channel, PairType(x[channel], 1U)); } } void insertFun(const Histogram* other, vigra::VigraFalseType) { for (int channel = 0; channel < CHANNELS; ++channel) { MapConstIterator const end = other->histogram[channel].end(); for (MapConstIterator i = other->histogram[channel].begin(); i != end; ++i) { insertInChannel(channel, *i); } } } void eraseFun(const InputPixelType& x, vigra::VigraFalseType) { for (int channel = 0; channel < CHANNELS; ++channel) { eraseInChannel(channel, PairType(x[channel], 1U)); } } void eraseFun(const Histogram* other, vigra::VigraFalseType) { for (int channel = 0; channel < CHANNELS; ++channel) { MapConstIterator const end = other->histogram[channel].end(); for (MapConstIterator i = other->histogram[channel].begin(); i != end; ++i) { eraseInChannel(channel, *i); } } } ResultPixelType entropyFun(vigra::VigraFalseType) const { const double max = static_cast(vigra::NumericTraits::max()); return ResultPixelType(vigra::NumericTraits::fromRealPromote(entropyOfChannel(0) * max), vigra::NumericTraits::fromRealPromote(entropyOfChannel(1) * max), vigra::NumericTraits::fromRealPromote(entropyOfChannel(2) * max)); } private: static size_t precomputedSize; static double* precomputedLog; static double* precomputedEntropy; MapType histogram[CHANNELS]; DataType totalCount[CHANNELS]; }; template void localEntropyIf(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc, MaskIterator mask_ul, MaskAccessor mask_acc, DestIterator dest_ul, DestAccessor dest_acc, vigra::Size2D size) { typedef typename SrcIterator::PixelType SrcPixelType; typedef typename DestIterator::PixelType DestPixelType; typedef Histogram ScratchPadType; vigra_precondition(src_lr.x - src_ul.x >= size.x && src_lr.y - src_ul.y >= size.y, "localEntropyIf(): window larger than image"); const typename SrcIterator::difference_type imageSize = src_lr - src_ul; ScratchPadType* const scratchPad = new ScratchPadType[imageSize.y + 1]; ScratchPadType::setPrecomputedEntropySize(size.x * size.y); const vigra::Diff2D border(size.x / 2, size.y / 2); const vigra::Diff2D deltaX(size.x / 2, 0); const vigra::Diff2D deltaXp1(size.x / 2 + 1, 0); const vigra::Diff2D deltaY(0, size.y / 2); // Fill scratch pad for the first time. { SrcIterator srcRow(src_ul + deltaX); SrcIterator const srcEnd(src_lr - deltaX); MaskIterator maskRow(mask_ul + deltaX); ScratchPadType* spRow(scratchPad); for (; srcRow.y < srcEnd.y; ++srcRow.y, ++maskRow.y, ++spRow) { SrcIterator srcCol(srcRow - deltaX); SrcIterator srcColEnd(srcRow + deltaX); MaskIterator maskCol(maskRow - deltaX); for (; srcCol.x <= srcColEnd.x; ++srcCol.x, ++maskCol.x) { if (mask_acc(maskCol)) { spRow->insert(src_acc(srcCol)); } } } } // Iterate through the image { SrcIterator srcCol(src_ul + border); SrcIterator const srcEnd(src_lr - border); MaskIterator maskCol(mask_ul + border); DestIterator destCol(dest_ul + border); ScratchPadType hist; // For each column in the source image... for (; srcCol.x < srcEnd.x; ++srcCol.x, ++maskCol.x, ++destCol.x) { SrcIterator srcRow(srcCol); MaskIterator maskRow(maskCol); DestIterator destRow(destCol); ScratchPadType* spRow(scratchPad + border.y); // Initialize running histogram of this column hist.clear(); for (ScratchPadType* s = spRow - border.y; s <= spRow + border.y; ++s) { hist.insert(s); } // Write one column of results for (; srcRow.y < srcEnd.y; ++srcRow.y, ++maskRow.y, ++destRow.y, ++spRow) { // Compute entropy if (mask_acc(maskRow)) { dest_acc.set(hist.entropy(), destRow); } // Update running histogram to next row hist.erase(spRow - border.y); // remove oldest row hist.insert(spRow + border.y + 1); // add next row } // Update scratch pad to next column for (srcRow = srcCol - deltaY, maskRow = maskCol - deltaY, spRow = scratchPad; srcRow.y < src_lr.y; ++srcRow.y, ++maskRow.y, ++spRow) { if (mask_acc(maskRow - deltaX)) { // remove oldest column spRow->erase(src_acc(srcRow - deltaX)); } if (mask_acc(maskRow + deltaXp1)) { // add next column spRow->insert(src_acc(srcRow + deltaXp1)); } } } } ScratchPadType::setPrecomputedEntropySize(0); delete [] scratchPad; } template inline void localEntropyIf(vigra::triple src, vigra::pair mask, vigra::pair dest, vigra::Size2D size) { localEntropyIf(src.first, src.second, src.third, mask.first, mask.second, dest.first, dest.second, size); } template inline void localStdDevIf(vigra::triple src, vigra::pair mask, vigra::pair dest, vigra::Size2D size) { localStdDevIf(src.first, src.second, src.third, mask.first, mask.second, dest.first, dest.second, size); } template class ImageMaskMultiplyFunctor { public: ImageMaskMultiplyFunctor(MaskPixelType d) : divisor(vigra::NumericTraits::toRealPromote(d)) {} template ImagePixelType operator()(const ImagePixelType& iP, const MaskPixelType& maskP) const { typedef typename vigra::NumericTraits::RealPromote RealImagePixelType; // Convert mask pixel to blend coefficient in range [0.0, 1.0]. const double maskCoeff = vigra::NumericTraits::toRealPromote(maskP) / divisor; const RealImagePixelType riP = vigra::NumericTraits::toRealPromote(iP); const RealImagePixelType blendP = riP * maskCoeff; return vigra::NumericTraits::fromRealPromote(blendP); } protected: const double divisor; }; template class ExposureFunctor : public std::unary_function { public: ExposureFunctor(double weight, ExposureWeight* weight_function, const InputAccessor& a) : weight_(weight), weight_function_(weight_function), acc_(a) {} ResultType operator()(const InputType& a) const { typedef typename vigra::NumericTraits::isScalar srcIsScalar; return f(a, srcIsScalar()); } protected: // grayscale template ResultType f(const T& a, vigra::VigraTrueType) const { const double y = vigra::NumericTraits::toRealPromote(a) / vigra::NumericTraits::max(); return vigra::NumericTraits::fromRealPromote(weight_ * weight_function_->weight(y)); } // RGB template ResultType f(const T& a, vigra::VigraFalseType) const { return f(acc_.operator()(a), vigra::VigraTrueType()); } const double weight_; ExposureWeight* weight_function_; InputAccessor acc_; }; template class CutoffExposureFunctor : public std::unary_function { public: CutoffExposureFunctor(double weight, ExposureWeight* weight_function, InputAccessor a, const AlternativePercentage& lc, const AlternativePercentage& uc, InputAccessor lca, InputAccessor uca) : weight_(weight), weight_function_(weight_function), acc_(a), lower_cutoff_(lc.instantiate()), upper_cutoff_(uc.instantiate()), lower_acc_(lca), upper_acc_(uca) { typedef typename InputAccessor::value_type value_type; const value_type max = vigra::NumericTraits::max(); if (lower_cutoff_ < value_type()) { std::cerr << command << ": negative lower exposure cutoff" << std::endl; exit(1); } if (upper_cutoff_ < value_type()) { std::cerr << command << ": negative upper exposure cutoff" << std::endl; exit(1); } if (lower_cutoff_ > upper_cutoff_) { std::cerr << command << ": lower exposure cutoff (" << lower_cutoff_ << "/" << max << " = " << 100.0 * lower_cutoff_ / max << "%) exceeds upper cutoff (" << upper_cutoff_ << "/" << max << " = " << 100.0 * upper_cutoff_ / max << "%)" << std::endl; exit(1); } } ResultType operator()(const InputType& a) const { typedef typename vigra::NumericTraits::isScalar srcIsScalar; return f(a, srcIsScalar()); } protected: // grayscale template ResultType f(const T& a, vigra::VigraTrueType) const { typedef typename vigra::NumericTraits::RealPromote RealType; const RealType ra = vigra::NumericTraits::toRealPromote(a); if (ra >= lower_cutoff_ && ra <= upper_cutoff_) { const double y = ra / vigra::NumericTraits::max(); return vigra::NumericTraits::fromRealPromote(weight_ * weight_function_->weight(y)); } else { return ResultType(); } } // RGB template ResultType f(const T& a, vigra::VigraFalseType) const { typedef typename T::value_type ValueType; typedef typename vigra::NumericTraits::RealPromote RealType; const RealType ra = vigra::NumericTraits::toRealPromote(acc_.operator()(a)); const RealType lower_ra = vigra::NumericTraits::toRealPromote(lower_acc_.operator()(a)); const RealType upper_ra = vigra::NumericTraits::toRealPromote(upper_acc_.operator()(a)); if (lower_ra >= lower_cutoff_ && upper_ra <= upper_cutoff_) { const double y = ra / vigra::NumericTraits::max(); return vigra::NumericTraits::fromRealPromote(weight_ * weight_function_->weight(y)); } else { return ResultType(); } } const double weight_; ExposureWeight* weight_function_; InputAccessor acc_; const double lower_cutoff_; const double upper_cutoff_; InputAccessor lower_acc_; InputAccessor upper_acc_; }; template class SaturationFunctor : public std::unary_function { public: SaturationFunctor(double w) : weight(w) {} inline ResultType operator()(const InputType& a) const { typedef typename vigra::NumericTraits::isScalar srcIsScalar; return f(a, srcIsScalar()); } protected: // grayscale template inline ResultType f(const T& a, vigra::VigraTrueType) const { return vigra::NumericTraits::zero(); } // RGB template inline ResultType f(const T& a, vigra::VigraFalseType) const { typedef typename T::value_type value_type; typedef vigra::NumericTraits value_traits; typedef vigra::NumericTraits result_traits; const value_type max = std::max(a.red(), std::max(a.green(), a.blue())); const value_type min = std::min(a.red(), std::min(a.green(), a.blue())); if (max == min) { return result_traits::zero(); } else { const double max_value = value_traits::isIntegral::asBool ? static_cast(value_traits::max()) : 1.0; const double sum = static_cast(max) + static_cast(min); const double difference = static_cast(max) - static_cast(min); const double saturation = sum <= max_value ? difference / sum : difference / (2.0 * max_value - sum); return result_traits::fromRealPromote(weight * saturation); } } const double weight; }; template class ContrastFunctor : public std::unary_function { public: ContrastFunctor(double w) : weight(w) {} inline ResultType operator()(const InputType& a) const { typedef typename vigra::NumericTraits::isScalar srcIsScalar; typedef typename vigra::NumericTraits::isIntegral scaleIsIntegral; return f(a, srcIsScalar(), scaleIsIntegral()); } protected: // grayscale, integral template inline ResultType f(const T& a, vigra::VigraTrueType, vigra::VigraTrueType) const { const typename vigra::NumericTraits::RealPromote ra = vigra::NumericTraits::toRealPromote(a); return vigra::NumericTraits::fromRealPromote(weight * ra / vigra::NumericTraits::max()); } // grayscale, floating-point template inline ResultType f(const T& a, vigra::VigraTrueType, vigra::VigraFalseType) const { const typename vigra::NumericTraits::RealPromote ra = vigra::NumericTraits::toRealPromote(a); return vigra::NumericTraits::fromRealPromote(weight * ra); } // RGB, integral template inline ResultType f(const T& a, vigra::VigraFalseType, vigra::VigraTrueType) const { typedef typename T::value_type TComponentType; typedef typename vigra::NumericTraits::RealPromote RealTComponentType; typedef typename ScaleType::value_type ScaleComponentType; const RealTComponentType ra = static_cast(a.lightness()); return vigra::NumericTraits::fromRealPromote(weight * ra / vigra::NumericTraits::max()); } // RGB, floating-point template inline ResultType f(const T& a, vigra::VigraFalseType, vigra::VigraFalseType) const { typedef typename T::value_type TComponentType; typedef typename vigra::NumericTraits::RealPromote RealTComponentType; const RealTComponentType ra = static_cast(a.lightness()); return vigra::NumericTraits::fromRealPromote(weight * ra); } const double weight; }; template class EntropyFunctor : public std::unary_function { public: typedef vigra::NumericTraits InputTraits; typedef vigra::NumericTraits ResultTraits; typedef ResultType result_type; EntropyFunctor(double w) : weight(w) {} ResultType operator()(const InputType& x) const { typedef typename InputTraits::isScalar srcIsScalar; return entropy(x, srcIsScalar()); } protected: // Grayscale ResultType entropy(const InputType& x, vigra::VigraTrueType) const { return ResultTraits::fromRealPromote(weight * ResultTraits::toRealPromote(x)); } // RGB ResultType entropy(const InputType& x, vigra::VigraFalseType) const { const typename ResultTraits::RealPromote minimum = ResultTraits::toRealPromote(std::min(std::min(x.red(), x.green()), x.blue())); return ResultTraits::fromRealPromote(weight * minimum); } private: const double weight; }; template struct MagnitudeAccessor { typedef ValueType value_type; template ValueType operator()(const Iterator& i) const {return std::abs(*i);} ValueType operator()(const ValueType* i) const {return std::abs(*i);} template ValueType operator()(const Iterator& i, Difference d) const {return std::abs(i[d]);} template void set(const Value& v, const Iterator& i) const { *i = vigra::detail::RequiresExplicitCast::cast(std::abs(v)); } template void set(const Value& v, Iterator& i) const { *i = vigra::detail::RequiresExplicitCast::cast(std::abs(v)); } template void set(const Value& v, const Iterator& i, const Difference& d) const { i[d] = vigra::detail::RequiresExplicitCast::cast(std::abs(v)); } }; template class ClampingFunctor : public std::unary_function { public: typedef vigra::NumericTraits InputTraits; ClampingFunctor(InputType lower, ResultType lowerValue, InputType upper, ResultType upperValue) : lo(lower), up(upper), loval(lowerValue), upval(upperValue) {} ResultType operator()(const InputType& x) const { typedef typename InputTraits::isScalar srcIsScalar; return clamp(x, srcIsScalar()); } protected: ResultType clamp(const InputType& x, vigra::VigraTrueType) const { return x <= lo ? loval : (x >= up ? upval : x); } // RGB ResultType clamp(const InputType& x, vigra::VigraFalseType) const { return ResultType(x.red() <= lo.red() ? loval.red() : (x.red() >= up.red() ? upval.red() : x.red()), x.green() <= lo.green() ? loval.green() : (x.green() >= up.green() ? upval.green() : x.green()), x.red() <= lo.red() ? loval.blue() : (x.blue() >= up.blue() ? upval.blue() : x.blue())); } private: const InputType lo, up; const ResultType loval, upval; }; // If the first argument is lower than THRESHOLD return the second // argument, i.e. the "fill-in" value multiplied with SCALE2, // otherwise return the first argument multiplied with SCALE1. template class FillInFunctor { public: FillInFunctor(InputType thr, double s1, double s2) : threshold(thr), scale1(s1), scale2(s2) {} ResultType operator()(const InputType& x, const InputType& y) const { if (x >= threshold) { return vigra::NumericTraits::fromRealPromote(scale1 * x); } else { return vigra::NumericTraits::fromRealPromote(scale2 * y); } } private: const InputType threshold; const double scale1, scale2; }; template void enfuseMask(vigra::triple src, vigra::pair mask, vigra::pair result) { typedef typename ImageType::value_type ImageValueType; typedef typename ImageType::PixelType PixelType; typedef typename vigra::NumericTraits::ValueType ScalarType; typedef typename MaskType::value_type MaskValueType; const typename ImageType::difference_type imageSize = src.second - src.first; // Exposure if (WExposure > 0.0) { typedef MultiGrayscaleAccessor MultiGrayAcc; MultiGrayAcc ga(GrayscaleProjector); if (ExposureLowerCutoff.is_effective() || ExposureUpperCutoff.is_effective()) { MultiGrayAcc lca(ExposureLowerCutoffGrayscaleProjector.empty() ? GrayscaleProjector : ExposureLowerCutoffGrayscaleProjector); MultiGrayAcc uca(ExposureUpperCutoffGrayscaleProjector.empty() ? ExposureLowerCutoffGrayscaleProjector : ExposureUpperCutoffGrayscaleProjector); CutoffExposureFunctor cef(WExposure, ExposureWeightFunction, ga, ExposureLowerCutoff, ExposureUpperCutoff, lca, uca); #ifdef DEBUG_EXPOSURE std::cout << "+ enfuseMask: cutoff - GrayscaleProjector = <" << GrayscaleProjector << ">\n" << "+ enfuseMask: ExposureLowerCutoffGrayscaleProjector = <" << ExposureLowerCutoffGrayscaleProjector << ">, cutoff spec = " << ExposureLowerCutoff.str() << ", actual cutoff = " << static_cast(ExposureLowerCutoff.instantiate()) << "\n+ enfuseMask: ExposureUpperCutoffGrayscaleProjector = <" << ExposureUpperCutoffGrayscaleProjector << ">, cutoff spec = " << ExposureUpperCutoff.str() << ", actual cutoff = " << static_cast(ExposureUpperCutoff.instantiate()) << "\n"; #endif vigra::omp::transformImageIf(src, mask, result, cef); } else { ExposureFunctor ef(WExposure, ExposureWeightFunction, ga); #ifdef DEBUG_EXPOSURE std::cout << "+ enfuseMask: plain - GrayscaleProjector = <" << GrayscaleProjector << ">\n"; #endif vigra::omp::transformImageIf(src, mask, result, ef); } } // Contrast if (WContrast > 0.0) { typedef typename vigra::NumericTraits::Promote LongScalarType; typedef IMAGETYPE GradImage; GradImage grad(imageSize); MultiGrayscaleAccessor ga(GrayscaleProjector); if (FilterConfig.edgeScale > 0.0) { #ifdef DEBUG_LOG std::cout << "+ Laplacian Edge Detection, scale = " << FilterConfig.edgeScale << " pixels" << std::endl; #endif GradImage laplacian(imageSize); if (FilterConfig.lceScale > 0.0) { #ifdef DEBUG_LOG std::cout << "+ Local Contrast Enhancement, (scale, amount) = " << FilterConfig.lceScale << " pixels, " << (100.0 * FilterConfig.lceFactor) << "%" << std::endl; #endif GradImage lce(imageSize); vigra::gaussianSharpening(src.first, src.second, ga, lce.upperLeft(), lce.accessor(), FilterConfig.lceFactor, FilterConfig.lceScale); vigra::laplacianOfGaussian(lce.upperLeft(), lce.lowerRight(), lce.accessor(), laplacian.upperLeft(), MagnitudeAccessor(), FilterConfig.edgeScale); } else { vigra::laplacianOfGaussian(src.first, src.second, ga, laplacian.upperLeft(), MagnitudeAccessor(), FilterConfig.edgeScale); } #ifdef DEBUG_LOG { vigra::FindMinMax minmax; vigra::inspectImage(srcImageRange(laplacian), minmax); std::cout << "+ after Laplacian and Magnitude: min = " << minmax.min << ", max = " << minmax.max << std::endl; } #endif const double minCurve = static_cast(MinCurvature.instantiate()); if (minCurve <= 0.0) { #ifdef DEBUG_LOG std::cout << "+ truncate values below " << -minCurve << std::endl;; #endif vigra::omp::transformImageIf(laplacian.upperLeft(), laplacian.lowerRight(), laplacian.accessor(), mask.first, mask.second, grad.upperLeft(), grad.accessor(), ClampingFunctor (static_cast(-minCurve), LongScalarType(), vigra::NumericTraits::max(), vigra::NumericTraits::max())); } else { #ifdef DEBUG_LOG std::cout << "+ merge local contrast and edges - switch at " << minCurve << std::endl; #endif GradImage localContrast(imageSize); // TODO: use localStdDev localStdDevIf(src.first, src.second, ga, mask.first, mask.second, localContrast.upperLeft(), localContrast.accessor(), vigra::Size2D(ContrastWindowSize, ContrastWindowSize)); vigra::omp::combineTwoImagesIf(laplacian.upperLeft(), laplacian.lowerRight(), laplacian.accessor(), localContrast.upperLeft(), localContrast.accessor(), mask.first, mask.second, grad.upperLeft(), grad.accessor(), FillInFunctor (static_cast(minCurve), // threshold 1.0, // scale factor for "laplacian" minCurve / vigra::NumericTraits::max())); // scale factor for "localContrast" } } else { #ifdef DEBUG_LOG std::cout << "+ Variance of Local Contrast" << std::endl; #endif localStdDevIf(src.first, src.second, ga, mask.first, mask.second, grad.upperLeft(), grad.accessor(), vigra::Size2D(ContrastWindowSize, ContrastWindowSize)); } #ifdef DEBUG_LOG { vigra::FindMinMax minmax; vigra::inspectImage(srcImageRange(grad), minmax); std::cout << "+ final grad: min = " << minmax.min << ", max = " << minmax.max << std::endl; } #endif ContrastFunctor cf(WContrast); #if defined(__clang__) vigra::omp::combineTwoImagesIf(srcImageRange(grad), result, mask, result, std::bind(std::plus(), std::bind(cf, std::placeholders::_1), std::placeholders::_2)); #else vigra::omp::combineTwoImagesIf(srcImageRange(grad), result, mask, result, [&cf](ScalarType x, const MaskValueType& y) {return cf(x) + y;}); #endif } // Saturation if (WSaturation > 0.0) { SaturationFunctor sf(WSaturation); #if defined(__clang__) vigra::omp::combineTwoImagesIf(src, result, mask, result, std::bind(std::plus(), std::bind(sf, std::placeholders::_1), std::placeholders::_2)); #else vigra::omp::combineTwoImagesIf(src, result, mask, result, [&sf](ImageValueType x, const MaskValueType& y) {return sf(x) + y;}); #endif } // Entropy if (WEntropy > 0.0) { typedef typename ImageType::PixelType PixelType; typedef typename vigra::NumericTraits::ValueType ScalarType; typedef IMAGETYPE Image; Image entropy(imageSize); if (EntropyLowerCutoff.is_effective() || EntropyUpperCutoff.is_effective()) { const ScalarType lowerCutoff = EntropyLowerCutoff.instantiate(); const ScalarType upperCutoff = EntropyUpperCutoff.instantiate(); #ifdef DEBUG_ENTROPY std::cout << "+ EntropyLowerCutoff.value = " << EntropyLowerCutoff.value() << ", " << "lowerCutoff = " << static_cast(lowerCutoff) << "\n" << "+ EntropyUpperCutoff.value = " << EntropyUpperCutoff.value() << ", " << "upperCutoff = " << static_cast(upperCutoff) << std::endl; #endif if (lowerCutoff < ScalarType()) { std::cerr << command << ": negative lower entropy cutoff" << std::endl; exit(1); } if (upperCutoff < ScalarType()) { std::cerr << command << ": negative upper entropy cutoff" << std::endl; exit(1); } if (lowerCutoff > upperCutoff) { const double max = static_cast(vigra::NumericTraits::max()); std::cerr << command << ": lower entropy cutoff (" << static_cast(lowerCutoff) << "/" << max << " = " << 100.0 * lowerCutoff / max << "%) exceeds upper cutoff (" << static_cast(upperCutoff) << "/" << max << " = " << 100.0 * upperCutoff / max << "%)" << std::endl; exit(1); } Image trunc(imageSize); ClampingFunctor cf((PixelType(lowerCutoff)), // IMPLEMENTATION NOTE: (PixelType(ScalarType())), // The extra parenthesis avoid a bug in the VC9 compiler. (PixelType(upperCutoff)), (PixelType(vigra::NumericTraits::max()))); vigra::omp::transformImage(src.first, src.second, src.third, trunc.upperLeft(), trunc.accessor(), cf); localEntropyIf(trunc.upperLeft(), trunc.lowerRight(), trunc.accessor(), mask.first, mask.second, entropy.upperLeft(), entropy.accessor(), vigra::Size2D(EntropyWindowSize, EntropyWindowSize)); } else { localEntropyIf(src.first, src.second, src.third, mask.first, mask.second, entropy.upperLeft(), entropy.accessor(), vigra::Size2D(EntropyWindowSize, EntropyWindowSize)); } EntropyFunctor ef(WEntropy); #if defined(__clang__) vigra::omp::combineTwoImagesIf(srcImageRange(entropy), result, mask, result, std::bind(std::plus(), std::bind(ef, std::placeholders::_1), std::placeholders::_2)); #else vigra::omp::combineTwoImagesIf(srcImageRange(entropy), result, mask, result, [&ef](PixelType x, const MaskValueType& y) {return ef(x) + y;}); #endif } }; /** Enfuse's main blending loop. Templatized to handle different image types. */ template void enfuseMain(const FileNameList& anInputFileNameList, const std::list& anImageInfoList, vigra::ImageExportInfo& anOutputImageInfo, vigra::Rect2D& anInputUnion) { typedef typename EnblendNumericTraits::ImagePixelComponentType ImagePixelComponentType; typedef typename EnblendNumericTraits::ImageType ImageType; typedef typename EnblendNumericTraits::AlphaType AlphaType; typedef IMAGETYPE MaskType; typedef typename MaskType::value_type MaskPixelType; typedef typename EnblendNumericTraits::ImagePyramidType ImagePyramidType; typedef typename EnblendNumericTraits::MaskPyramidPixelType MaskPyramidPixelType; typedef typename EnblendNumericTraits::MaskPyramidType MaskPyramidType; enum {ImagePyramidIntegerBits = EnblendNumericTraits::ImagePyramidIntegerBits}; enum {ImagePyramidFractionBits = EnblendNumericTraits::ImagePyramidFractionBits}; enum {MaskPyramidIntegerBits = EnblendNumericTraits::MaskPyramidIntegerBits}; enum {MaskPyramidFractionBits = EnblendNumericTraits::MaskPyramidFractionBits}; typedef typename EnblendNumericTraits::SKIPSMImagePixelType SKIPSMImagePixelType; typedef typename EnblendNumericTraits::SKIPSMAlphaPixelType SKIPSMAlphaPixelType; typedef typename EnblendNumericTraits::SKIPSMMaskPixelType SKIPSMMaskPixelType; // List of input image / input alpha / mask triples typedef std::list< vigra::triple > imageListType; typedef typename imageListType::iterator imageListIteratorType; imageListType imageList; // Sum of all masks MaskType *normImage = new MaskType(anInputUnion.size()); // Result image. Alpha will be union of all input alphas. std::pair outputPair(static_cast(nullptr), new AlphaType(anInputUnion.size())); std::list imageInfoList(anImageInfoList); const unsigned numberOfImages = imageInfoList.size(); unsigned m = 0; FileNameList::const_iterator inputFileNameIterator(anInputFileNameList.begin()); while (!imageInfoList.empty()) { vigra::Rect2D imageBB; std::pair imagePair = assemble(imageInfoList, anInputUnion, imageBB); MaskType* mask = new MaskType(anInputUnion.size()); if (LoadMasks) { // IMPLEMENTATION NOTE: For simplicity of the code, here // we also load in hard masks. Computing the set of hard // masks from a set of soft masks is done by maximum // selection, which is an idempotent function. const std::string maskFilename = enblend::expandFilenameTemplate(UseHardMask ? HardMaskTemplate : SoftMaskTemplate, numberOfImages, *inputFileNameIterator, OutputFileName, m); if (can_open_file(maskFilename)) { vigra::ImageImportInfo maskInfo(maskFilename.c_str()); if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << command << ": info: loading " << (UseHardMask ? "hard" : "soft") << "mask \"" << maskFilename << "\"" << std::endl; } if (!maskInfo.isGrayscale()) { std::cerr << command << ": mask image \"" << maskFilename << "\" is not grayscale" << std::endl; exit(1); } if (maskInfo.numExtraBands() != 0) { std::cerr << command << ": mask image \"" << maskFilename << "\" must not have an alpha channel" << std::endl; exit(1); } if (maskInfo.width() != anInputUnion.width() || maskInfo.height() != anInputUnion.height()) { std::cerr << command << ": warning: mask in \"" << maskFilename << "\" has size " << "(" << maskInfo.width() << "x" << maskInfo.height() << "),\n" << command << ": warning: but image union has size " << anInputUnion.size() << ";\n" << command << ": note: make sure this is the right mask for the given images" << std::endl; } importImage(maskInfo, destImage(*mask)); } else { // Cannot read mask file. We already issued an error // message through can_open_file(). exit(1); } } else { enfuseMask(srcImageRange(*(imagePair.first)), srcImage(*(imagePair.second)), destImage(*mask)); } if (SaveMasks) { const std::string mask_pixel_type = to_upper_copy(parameter::as_string("mask-save-pixel-type", "float")); const std::string maskFilename = enblend::expandFilenameTemplate(SoftMaskTemplate, numberOfImages, *inputFileNameIterator, OutputFileName, m); if (maskFilename == *inputFileNameIterator) { std::cerr << command << ": will not overwrite input image \"" << *inputFileNameIterator << "\" with soft mask file" << std::endl; exit(1); } else if (maskFilename == OutputFileName) { std::cerr << command << ": will not overwrite output image \"" << OutputFileName << "\" with soft mask file" << std::endl; exit(1); } else { if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << command << ": info: saving soft mask \"" << maskFilename << "\"" << std::endl; } vigra::ImageExportInfo maskInfo(maskFilename.c_str()); maskInfo.setXResolution(ImageResolution.x); maskInfo.setYResolution(ImageResolution.y); maskInfo.setCompression(MASK_COMPRESSION); maskInfo.setPixelType(mask_pixel_type.c_str()); exportImage(srcImageRange(*mask), maskInfo); } } // Make output alpha the union of all input alphas. vigra::omp::copyImageIf(srcImageRange(*(imagePair.second)), maskImage(*(imagePair.second)), destImage(*(outputPair.second))); // Add the mask to the norm image. vigra::omp::combineTwoImages(srcImageRange(*mask), srcImage(*normImage), destImage(*normImage), Arg1() + Arg2()); imageList.push_back(vigra::make_triple(imagePair.first, imagePair.second, mask)); ++m; ++inputFileNameIterator; } if (StopAfterMaskGeneration && !UseHardMask) { exit(0); } const int totalImages = imageList.size(); typename EnblendNumericTraits::MaskPixelType maxMaskPixelType = vigra::NumericTraits::MaskPixelType>::max(); if (UseHardMask) { if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << command << ": info: creating hard blend mask" << std::endl; } const vigra::Size2D sz = normImage->size(); imageListIteratorType imageIter; #ifdef OPENMP #pragma omp parallel for private (imageIter) #endif for (int y = 0; y < sz.y; ++y) { for (int x = 0; x < sz.x; ++x) { float max = 0.0f; int maxi = 0; int i = 0; for (imageIter = imageList.begin(); imageIter != imageList.end(); ++imageIter) { const float w = static_cast((*imageIter->third)(x, y)); if (w > max) { max = w; maxi = i; } i++; } i = 0; for (imageIter = imageList.begin(); imageIter != imageList.end(); ++imageIter) { if (max == 0.0f) { (*imageIter->third)(x, y) = static_cast(maxMaskPixelType) / totalImages; } else if (i == maxi) { (*imageIter->third)(x, y) = maxMaskPixelType; } else { (*imageIter->third)(x, y) = 0.0f; } i++; } } } unsigned i = 0; if (SaveMasks) { const std::string mask_pixel_type = to_upper_copy(parameter::as_string("mask-save-pixel-type", "float")); for (imageIter = imageList.begin(), inputFileNameIterator = anInputFileNameList.begin(); imageIter != imageList.end(); ++imageIter, ++inputFileNameIterator) { const std::string maskFilename = enblend::expandFilenameTemplate(HardMaskTemplate, imageList.size(), *inputFileNameIterator, OutputFileName, i); if (maskFilename == *inputFileNameIterator) { std::cerr << command << ": will not overwrite input image \"" << *inputFileNameIterator << "\" with hard mask" << std::endl; exit(1); } else if (maskFilename == OutputFileName) { std::cerr << command << ": will not overwrite output image \"" << OutputFileName << "\" with hard mask" << std::endl; exit(1); } else { if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << command << ": info: saving hard mask \"" << maskFilename << "\"" << std::endl; } vigra::ImageExportInfo maskInfo(maskFilename.c_str()); maskInfo.setXResolution(ImageResolution.x); maskInfo.setYResolution(ImageResolution.y); maskInfo.setCompression(MASK_COMPRESSION); maskInfo.setPixelType(mask_pixel_type.c_str()); exportImage(srcImageRange(*(imageIter->third)), maskInfo); } i++; } } } if (StopAfterMaskGeneration) { exit(0); } vigra::Rect2D junkBB; const unsigned int numLevels = roiBounds(anInputUnion, anInputUnion, anInputUnion, anInputUnion, junkBB, WrapAround != OpenBoundaries); std::vector *resultLP = nullptr; m = 0; while (!imageList.empty()) { vigra::triple imageTriple = imageList.front(); imageList.erase(imageList.begin()); std::ostringstream oss0; oss0 << "imageGP" << m << "_"; // imageLP is constructed using the image's own alpha channel // as the boundary for extrapolation. std::vector *imageLP = laplacianPyramid( oss0.str().c_str(), numLevels, WrapAround != OpenBoundaries, srcImageRange(*(imageTriple.first)), maskImage(*(imageTriple.second))); delete imageTriple.first; delete imageTriple.second; //std::ostringstream oss1; //oss1 << "imageLP" << m << "_"; //exportPyramid(imageLP, oss1.str().c_str()); if (!UseHardMask) { // Normalize the mask coefficients. // Scale to the range expected by the MaskPyramidPixelType. vigra::omp::combineTwoImages(srcImageRange(*(imageTriple.third)), srcImage(*normImage), destImage(*(imageTriple.third)), ifThenElse(Arg2() > Param(0.0), Param(maxMaskPixelType) * Arg1() / Arg2(), Param(maxMaskPixelType / totalImages))); } // maskGP is constructed using the union of the input alpha channels // as the boundary for extrapolation. std::vector *maskGP = gaussianPyramid (numLevels, WrapAround != OpenBoundaries, srcImageRange(*(imageTriple.third)), maskImage(*(outputPair.second))); delete imageTriple.third; //std::ostringstream oss2; //oss2 << "maskGP" << m << "_"; //exportPyramid(maskGP, oss2.str().c_str()); ConvertScalarToPyramidFunctor::MaskPixelType, MaskPyramidPixelType, MaskPyramidIntegerBits, MaskPyramidFractionBits> maskConvertFunctor; MaskPyramidPixelType maxMaskPyramidPixelValue = maskConvertFunctor(maxMaskPixelType); for (unsigned int i = 0; i < maskGP->size(); ++i) { // Multiply image lp with the mask gp. vigra::omp::combineTwoImages(srcImageRange(*((*imageLP)[i])), srcImage(*((*maskGP)[i])), destImage(*((*imageLP)[i])), ImageMaskMultiplyFunctor(maxMaskPyramidPixelValue)); // Done with maskGP. delete (*maskGP)[i]; } delete maskGP; //std::ostringstream oss3; //oss3 << "multLP" << m << "_"; //exportPyramid(imageLP, oss3.str().c_str()); if (resultLP != nullptr) { // Add imageLP to resultLP. for (unsigned int i = 0; i < imageLP->size(); ++i) { vigra::omp::combineTwoImages(srcImageRange(*((*imageLP)[i])), srcImage(*((*resultLP)[i])), destImage(*((*resultLP)[i])), Arg1() + Arg2()); delete (*imageLP)[i]; } delete imageLP; } else { resultLP = imageLP; } //std::ostringstream oss4; //oss4 << "resultLP" << m << "_"; //exportPyramid(resultLP, oss4.str().c_str()); ++m; } delete normImage; //exportPyramid(resultLP, "resultLP"); collapsePyramid(WrapAround != OpenBoundaries, resultLP); outputPair.first = new ImageType(anInputUnion.size()); copyFromPyramidImageIf (srcImageRange(*((*resultLP)[0])), maskImage(*(outputPair.second)), destImage(*(outputPair.first))); // Delete result pyramid. for (unsigned int i = 0; i < resultLP->size(); ++i) { delete (*resultLP)[i]; } delete resultLP; checkpoint(outputPair, anOutputImageInfo); delete outputPair.first; delete outputPair.second; } } // namespace enblend #endif /* __ENFUSE_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/timer.h0000644000175000017500000000774012641706002013260 00000000000000/* * Copyright (C) 2013-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef TIMER_H_INCLUDED #define TIMER_H_INCLUDED #ifdef HAVE_CONFIG_H #include #endif #include #ifdef HAVE_SYS_TIMES_H #include // times() #endif #include // clock_t, clock(); timespec, clock_gettime() #ifdef WIN32 #include #endif namespace timer { class Interface { public: // The constructor of each derived class shall call start(). virtual ~Interface() {} // Reset counter to zero and start a new measurement. virtual void start() = 0; // Stop measurement. After stop() all calls to value() return // the same result. virtual void stop() = 0; // Continue to measure after counter has been stopped. Do not // reset the counter, instead accumulate. virtual void restart() = 0; // Answer the time passed between calls to start() and stop() // or restart() and stop() in seconds. virtual double value() const = 0; }; // class Interface class StandardWallClock : public Interface { public: StandardWallClock(); void start(); void stop(); void restart(); double value() const; private: clock_t value_; clock_t start_; clock_t stop_; }; // class StandardWallClock #ifdef HAVE_CLOCK_GETTIME class RealTimeWallClock : public Interface { public: RealTimeWallClock(); void restart(); void start(); void stop(); double value() const; private: typedef std::uint64_t value_t; // typedef decltype(struct timespec . tv_sec) seconds_t; // typedef decltype(struct timespec . tv_nsec) nano_seconds_t; value_t value_; // unit: nano seconds timespec start_; timespec stop_; }; // class RealTimeWallClock #define WallClock RealTimeWallClock #else #define WallClock StandardWallClock #endif // HAVE_CLOCK_GETTIME #ifdef WIN32 class ProcessorTime : public Interface { public: ProcessorTime(); void start(); void stop(); void restart(); protected: ULONGLONG user_value_; ULONGLONG system_value_; ULONGLONG start_user_value_; ULONGLONG start_system_value_; ULONGLONG start_idle_value_; }; // class ProcessorTime #elif defined(HAVE_SYS_TIMES_H) class ProcessorTime : public Interface { public: ProcessorTime(); void start(); void stop(); void restart(); protected: clock_t user_value_; clock_t system_value_; tms start_; tms stop_; }; // class ProcessorTime #else // Null class -- does nothing class ProcessorTime : public Interface { public: void start() {} void stop() {} void restart() {} }; // class ProcessorTime #endif class UserTime : public ProcessorTime { public: double value() const; }; // class UserTime class SystemTime : public ProcessorTime { public: double value() const; }; // class SystemTime } // namespace timer #endif // TIMER_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/minimizer.cc0000644000175000017500000004362512673533541014316 00000000000000/* * Copyright (C) 2012-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "minimizer.h" Minimizer::Minimizer(size_t a_dimension) : dimension_(a_dimension), maximum_iteration_(ITERATIONS_PER_DIMENSION * a_dimension), iteration_(0U), f_goal_(boost::none), absolute_error_(sqrt(std::numeric_limits::epsilon())) {} Minimizer::Minimizer(const Minimizer& a_minimizer) : dimension_(a_minimizer.dimension_), maximum_iteration_(a_minimizer.maximum_iteration_), iteration_(a_minimizer.iteration_), f_goal_(a_minimizer.f_goal_), absolute_error_(a_minimizer.absolute_error_) {} Minimizer& Minimizer::operator=(const Minimizer& a_minimizer) { if (this != &a_minimizer) { dimension_ = a_minimizer.dimension_; maximum_iteration_ = a_minimizer.maximum_iteration_; iteration_ = a_minimizer.iteration_; f_goal_ = a_minimizer.f_goal_; absolute_error_ = a_minimizer.absolute_error_; } return *this; } Minimizer* Minimizer::set_maximum_number_of_iterations(unsigned n) { maximum_iteration_ = n; return this; } Minimizer* Minimizer::unset_maximum_number_of_iterations() { maximum_iteration_ = boost::none; return this; } Minimizer* Minimizer::set_goal(double a_goal) { f_goal_ = a_goal; return this; } Minimizer* Minimizer::unset_goal() { f_goal_ = boost::none; return this; } Minimizer* Minimizer::set_absolute_error(double an_absolute_error) { if (an_absolute_error > 0.0) { absolute_error_ = std::max(an_absolute_error, sqrt(std::numeric_limits::epsilon())); return this; } else { throw std::domain_error("Minimizer1D::set_absolute_error"); } } Minimizer* Minimizer::unset_absolute_error() { absolute_error_ = boost::none; return this; } bool Minimizer::has_reached_goal() const { return f_goal_ && f_minimum() <= *f_goal_; } bool Minimizer::has_reached_maximum_iteration() const { return maximum_iteration_ && iteration_ >= *maximum_iteration_; } double Minimizer::absolute_error() const { return absolute_error_ ? *absolute_error_ : sqrt(std::numeric_limits::epsilon()); } //////////////////////////////////////////////////////////////////////// Minimizer1D::Minimizer1D(const gsl_function& a_function, double x_minimum, double x_lower, double x_upper) : Minimizer(1U), minimizer_(nullptr), function_(a_function), x_minimum_(x_minimum), x_lower_(x_lower), x_upper_(x_upper), relative_error_(0.0) { require_ordered_x(); } Minimizer1D::Minimizer1D(const Minimizer1D& a_minimizer) : Minimizer(a_minimizer), minimizer_(nullptr), function_(a_minimizer.function_), x_minimum_(a_minimizer.x_minimum_), x_lower_(a_minimizer.x_lower_), x_upper_(a_minimizer.x_upper_), relative_error_(a_minimizer.relative_error_) {} Minimizer1D& Minimizer1D::operator=(const Minimizer1D& a_minimizer) { if (this != &a_minimizer) { Minimizer::operator=(a_minimizer); function_ = a_minimizer.function_; x_minimum_ = a_minimizer.x_minimum_; x_lower_ = a_minimizer.x_lower_; x_upper_ = a_minimizer.x_upper_; relative_error_ = a_minimizer.relative_error_; gsl_min_fminimizer_free(minimizer_); minimizer_ = nullptr; initialize(a_minimizer.type_); } return *this; } std::string Minimizer1D::proper_name() const { return std::string(gsl_min_fminimizer_name(minimizer_)); } void Minimizer1D::set_bracket(const gsl_function& a_function, double x_minimum, double x_lower, double x_upper) { require_ordered_x(); function_ = a_function; x_minimum_ = x_minimum; x_lower_ = x_lower; x_upper_ = x_upper; const int status = gsl_min_fminimizer_set(minimizer_, &function_, x_minimum_, x_lower_, x_upper_); if (status == GSL_EINVAL) { throw minimum_not_bracketed("Minimizer1D::set_bracket: minimum not bracketed"); } else if (status != GSL_SUCCESS) { throw std::runtime_error("Minimizer1D::set_bracket"); } } Minimizer1D* Minimizer1D::set_relative_error(double a_relative_error) { if (a_relative_error >= 0.0) { relative_error_ = a_relative_error; return this; } else { throw std::domain_error("Minimizer1D::set_relative_error"); } } Minimizer1D* Minimizer1D::unset_relative_error() { relative_error_ = boost::none; return this; } void Minimizer1D::run() { int test_status = GSL_CONTINUE; while (test_status == GSL_CONTINUE) { next_iteration(); const int minimizer_status = gsl_min_fminimizer_iterate(minimizer_); if (minimizer_status == GSL_EBADFUNC || // singular point or minimizer_status == GSL_FAILURE) // could not improve minimum { break; } x_lower_ = gsl_min_fminimizer_x_lower(minimizer_); x_upper_ = gsl_min_fminimizer_x_upper(minimizer_); x_minimum_ = gsl_min_fminimizer_x_minimum(minimizer_); if (has_reached_goal() || has_reached_maximum_iteration()) { break; } test_status = gsl_min_test_interval(x_lower_, x_upper_, absolute_error(), relative_error()); } } void Minimizer1D::require_ordered_x() const { if (!(x_lower_ <= x_minimum_ && x_minimum_ <= x_upper_)) { throw std::runtime_error("Minimizer1D::require_ordered_x: x-values not ascending"); } } void Minimizer1D::initialize(const gsl_min_fminimizer_type* a_minimizer_type) { assert(a_minimizer_type != nullptr); type_ = a_minimizer_type; assert(minimizer_ == nullptr); minimizer_ = gsl_min_fminimizer_alloc(type_); if (minimizer_ == nullptr) { throw std::runtime_error("Minimizer1D::initialize: no memory"); } set_bracket(function_, x_minimum_, x_lower_, x_upper_); } double Minimizer1D::relative_error() const { return relative_error_ ? *relative_error_ : 0.0; } bool Minimizer1D::has_reached_tolerance() const { return gsl_min_test_interval(x_lower_, x_upper_, absolute_error(), relative_error()) == GSL_SUCCESS; } //////////////////////////////////////////////////////////////////////// GoldenSectionMinimizer1D::GoldenSectionMinimizer1D(const gsl_function& a_function, double x_minimum, double x_lower, double x_upper) : Minimizer1D(a_function, x_minimum, x_lower, x_upper) { initialize(gsl_min_fminimizer_goldensection); } GoldenSectionMinimizer1D::GoldenSectionMinimizer1D(const GoldenSectionMinimizer1D& a_minimizer) : Minimizer1D(a_minimizer) { initialize(gsl_min_fminimizer_goldensection); } //////////////////////////////////////////////////////////////////////// BrentMinimizer1D::BrentMinimizer1D(const gsl_function& a_function, double x_minimum, double x_lower, double x_upper) : Minimizer1D(a_function, x_minimum, x_lower, x_upper) { initialize(gsl_min_fminimizer_brent); } BrentMinimizer1D::BrentMinimizer1D(const BrentMinimizer1D& a_minimizer) : Minimizer1D(a_minimizer) { initialize(gsl_min_fminimizer_brent); } //////////////////////////////////////////////////////////////////////// GillMurrayMinimizer1D::GillMurrayMinimizer1D(const gsl_function& a_function, double x_minimum, double x_lower, double x_upper) : Minimizer1D(a_function, x_minimum, x_lower, x_upper) { initialize(gsl_min_fminimizer_quad_golden); } GillMurrayMinimizer1D::GillMurrayMinimizer1D(const GillMurrayMinimizer1D& a_minimizer) : Minimizer1D(a_minimizer) { initialize(gsl_min_fminimizer_quad_golden); } //////////////////////////////////////////////////////////////////////// MinimizerMultiDimensionNoDerivative::MinimizerMultiDimensionNoDerivative (const gsl_multimin_function& a_function, const array_type& a_start, const array_type& some_step_sizes) : Minimizer(a_start.size()), minimizer_(nullptr), function_(a_function), xs_(gsl_vector_alloc(a_start.size())), step_sizes_(gsl_vector_alloc(some_step_sizes.size())), characteristic_size_(std::numeric_limits::max()) { if (xs_ == nullptr || step_sizes_ == nullptr) { throw std::runtime_error("MinimizerMultiDimensionNoDerivative::constructor: no memory"); } if (a_start.size() != some_step_sizes.size()) { throw std::invalid_argument("MinimizerMultiDimensionNoDerivative::constructor: dimension mismatch"); } copy_to_gsl_vector(a_start.begin(), a_start.end(), xs_); initialize_step_sizes(some_step_sizes); } MinimizerMultiDimensionNoDerivative::MinimizerMultiDimensionNoDerivative (const gsl_multimin_function& a_function, const array_type& a_start) : Minimizer(a_start.size()), minimizer_(nullptr), function_(a_function), xs_(gsl_vector_alloc(a_start.size())), step_sizes_(gsl_vector_alloc(a_start.size())), characteristic_size_(std::numeric_limits::max()) { if (xs_ == nullptr || step_sizes_ == nullptr) { throw std::runtime_error("MinimizerMultiDimensionNoDerivative::constructor: no memory"); } copy_to_gsl_vector(a_start.begin(), a_start.end(), xs_); gsl_vector_set_all(step_sizes_, 1.0); } MinimizerMultiDimensionNoDerivative::MinimizerMultiDimensionNoDerivative (const MinimizerMultiDimensionNoDerivative& a_minimizer) : Minimizer(a_minimizer), minimizer_(nullptr), function_(a_minimizer.function_), xs_(gsl_vector_alloc(dimension())), step_sizes_(gsl_vector_alloc(dimension())), characteristic_size_(a_minimizer.characteristic_size_) { if (xs_ == nullptr || step_sizes_ == nullptr) { throw std::runtime_error("MinimizerMultiDimensionNoDerivative::constructor: no memory"); } gsl_vector_memcpy(xs_, a_minimizer.xs_); gsl_vector_memcpy(step_sizes_, a_minimizer.step_sizes_); } MinimizerMultiDimensionNoDerivative& MinimizerMultiDimensionNoDerivative::operator=(const MinimizerMultiDimensionNoDerivative& a_minimizer) { if (this != &a_minimizer) { Minimizer::operator=(a_minimizer); // or equivalently: this->Minimizer::operator=(a_minimizer) function_ = a_minimizer.function_; characteristic_size_ = a_minimizer.characteristic_size_; if (dimension() != a_minimizer.dimension()) { set_dimension(a_minimizer.dimension()); gsl_vector_free(xs_); gsl_vector_free(step_sizes_); xs_ = gsl_vector_alloc(a_minimizer.dimension()); step_sizes_ = gsl_vector_alloc(a_minimizer.dimension()); if (xs_ == nullptr || step_sizes_ == nullptr) { throw std::runtime_error("MinimizerMultiDimensionNoDerivative::operator=: no memory"); } } gsl_vector_memcpy(xs_, a_minimizer.xs_); gsl_vector_memcpy(step_sizes_, a_minimizer.step_sizes_); gsl_multimin_fminimizer_free(minimizer_); minimizer_ = nullptr; initialize(a_minimizer.type_); } return *this; } MinimizerMultiDimensionNoDerivative::~MinimizerMultiDimensionNoDerivative() { gsl_vector_free(step_sizes_); gsl_vector_free(xs_); gsl_multimin_fminimizer_free(minimizer_); } void MinimizerMultiDimensionNoDerivative::set_start(const array_type& a_start) { if (a_start.size() == dimension()) { copy_to_gsl_vector(a_start.begin(), a_start.end(), xs_); } else { throw std::invalid_argument("MinimizerMultiDimensionNoDerivative::set_start: dimension mismatch"); } set(); } void MinimizerMultiDimensionNoDerivative::set_step_sizes(const array_type& some_step_sizes) { initialize_step_sizes(some_step_sizes); set(); } std::string MinimizerMultiDimensionNoDerivative::proper_name() const { return std::string(gsl_multimin_fminimizer_name(minimizer_)); } void MinimizerMultiDimensionNoDerivative::run() { int test_status = GSL_CONTINUE; while (test_status == GSL_CONTINUE) { next_iteration(); const int minimizer_status = gsl_multimin_fminimizer_iterate(minimizer_); if (minimizer_status == GSL_ENOPROG || // could not improve minimum has_reached_goal() || has_reached_maximum_iteration()) { break; } characteristic_size_ = gsl_multimin_fminimizer_size(minimizer_); test_status = gsl_multimin_test_size(characteristic_size_, absolute_error()); } characteristic_size_ = gsl_multimin_fminimizer_size(minimizer_); gsl_vector_memcpy(xs_, gsl_multimin_fminimizer_x(minimizer_)); } double MinimizerMultiDimensionNoDerivative::f_minimum() const { return gsl_multimin_fminimizer_minimum(minimizer_); } void MinimizerMultiDimensionNoDerivative::initialize_step_sizes(const array_type& some_step_sizes) { if (some_step_sizes.size() == dimension()) { array_type::const_iterator x = some_step_sizes.begin(); unsigned i = 0U; while (x != some_step_sizes.end()) { if (*x > 0.0) { gsl_vector_set(step_sizes_, i, *x); } else { throw std::runtime_error("MinimizerMultiDimensionNoDerivative::initialize_step_sizes: " "non-positive step size"); } ++x; ++i; } } else { throw std::invalid_argument("MinimizerMultiDimensionNoDerivative::initialize_step_sizes: " "dimension mismatch"); } } void MinimizerMultiDimensionNoDerivative::set() { assert(minimizer_ != nullptr); const int status = gsl_multimin_fminimizer_set(minimizer_, &function_, xs_, step_sizes_); if (status != GSL_SUCCESS) { throw std::runtime_error("MinimizerMultiDimensionNoDerivative::set"); } } void MinimizerMultiDimensionNoDerivative::initialize(const gsl_multimin_fminimizer_type* a_fminimizer_type) { assert(a_fminimizer_type != nullptr); type_ = a_fminimizer_type; assert(minimizer_ == nullptr); minimizer_ = gsl_multimin_fminimizer_alloc(type_, dimension()); if (minimizer_ == nullptr) { throw std::runtime_error("MinimizerMultiDimensionNoDerivative::initialize: no memory"); } set(); } //////////////////////////////////////////////////////////////////////// MinimizerMultiDimensionSimplex::MinimizerMultiDimensionSimplex(const gsl_multimin_function& a_function, const array_type& a_start, const array_type& some_step_sizes) : MinimizerMultiDimensionNoDerivative(a_function, a_start, some_step_sizes) { initialize(gsl_multimin_fminimizer_nmsimplex); } MinimizerMultiDimensionSimplex::MinimizerMultiDimensionSimplex(const gsl_multimin_function& a_function, const array_type& a_start) : MinimizerMultiDimensionNoDerivative(a_function, a_start) { initialize(gsl_multimin_fminimizer_nmsimplex); } MinimizerMultiDimensionSimplex::MinimizerMultiDimensionSimplex(const MinimizerMultiDimensionSimplex& a_minimizer) : MinimizerMultiDimensionNoDerivative(a_minimizer) { initialize(gsl_multimin_fminimizer_nmsimplex); } //////////////////////////////////////////////////////////////////////// MinimizerMultiDimensionSimplex2::MinimizerMultiDimensionSimplex2(const gsl_multimin_function& a_function, const array_type& a_start, const array_type& some_step_sizes) : MinimizerMultiDimensionNoDerivative(a_function, a_start, some_step_sizes) { initialize(gsl_multimin_fminimizer_nmsimplex2); } MinimizerMultiDimensionSimplex2::MinimizerMultiDimensionSimplex2(const gsl_multimin_function& a_function, const array_type& a_start) : MinimizerMultiDimensionNoDerivative(a_function, a_start) { initialize(gsl_multimin_fminimizer_nmsimplex2); } MinimizerMultiDimensionSimplex2::MinimizerMultiDimensionSimplex2(const MinimizerMultiDimensionSimplex2& a_minimizer) : MinimizerMultiDimensionNoDerivative(a_minimizer) { initialize(gsl_multimin_fminimizer_nmsimplex2); } //////////////////////////////////////////////////////////////////////// MinimizerMultiDimensionSimplex2Randomized::MinimizerMultiDimensionSimplex2Randomized (const gsl_multimin_function& a_function, const array_type& a_start, const array_type& some_step_sizes) : MinimizerMultiDimensionNoDerivative(a_function, a_start, some_step_sizes) { initialize(gsl_multimin_fminimizer_nmsimplex2rand); } MinimizerMultiDimensionSimplex2Randomized::MinimizerMultiDimensionSimplex2Randomized (const gsl_multimin_function& a_function, const array_type& a_start) : MinimizerMultiDimensionNoDerivative(a_function, a_start) { initialize(gsl_multimin_fminimizer_nmsimplex2rand); } MinimizerMultiDimensionSimplex2Randomized::MinimizerMultiDimensionSimplex2Randomized (const MinimizerMultiDimensionSimplex2Randomized& a_minimizer) : MinimizerMultiDimensionNoDerivative(a_minimizer) { initialize(gsl_multimin_fminimizer_nmsimplex2rand); } enblend-enfuse-4.2/src/common.h0000644000175000017500000007336712641706002013440 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __COMMON_H__ #define __COMMON_H__ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "error_message.h" #include "filenameparse.h" #define NUMERIC_OPTION_DELIMITERS ";:/" //< numeric-option-delimiters ;:/ #define PATH_OPTION_DELIMITERS ",;:" //< path-option-delimiters ,;: #define ASSIGNMENT_CHARACTERS "=" //< assignment-characters = #define MASK_COMPRESSION "DEFLATE" // IMPLEMENTATION NOTE: For 30 or more pyramid levels, the full width // will just barely fit in a 32-bit integer. When this range is added // to a bounding box it will certainly overflow the vigra::Diff2D. #define MAX_PYRAMID_LEVELS 29 //< maximum-pyramid-levels 29 // Colors used in the optimizer visualization #define VISUALIZE_RGB_COLOR_BLUE1 vigra::RGBValue( 0, 0, 255) #define VISUALIZE_RGB_COLOR_BLUE2 vigra::RGBValue( 0, 0, 238) #define VISUALIZE_RGB_COLOR_BLUE3 vigra::RGBValue( 0, 0, 205) #define VISUALIZE_RGB_COLOR_BLUE4 vigra::RGBValue( 0, 0, 139) #define VISUALIZE_RGB_COLOR_CYAN1 vigra::RGBValue( 0, 255, 255) #define VISUALIZE_RGB_COLOR_CYAN2 vigra::RGBValue( 0, 238, 238) #define VISUALIZE_RGB_COLOR_CYAN3 vigra::RGBValue( 0, 205, 205) #define VISUALIZE_RGB_COLOR_CYAN4 vigra::RGBValue( 0, 139, 139) #define VISUALIZE_RGB_COLOR_GRAY0 vigra::RGBValue( 0, 0, 0) #define VISUALIZE_RGB_COLOR_GRAY63 vigra::RGBValue( 63, 63, 63) #define VISUALIZE_RGB_COLOR_GRAY127 vigra::RGBValue(127, 127, 127) #define VISUALIZE_RGB_COLOR_GRAY139 vigra::RGBValue(139, 139, 139) #define VISUALIZE_RGB_COLOR_GRAY191 vigra::RGBValue(191, 191, 191) #define VISUALIZE_RGB_COLOR_GRAY205 vigra::RGBValue(205, 205, 205) #define VISUALIZE_RGB_COLOR_GRAY238 vigra::RGBValue(238, 238, 238) #define VISUALIZE_RGB_COLOR_GRAY255 vigra::RGBValue(255, 255, 255) #define VISUALIZE_RGB_COLOR_GREEN1 vigra::RGBValue( 0, 255, 0) #define VISUALIZE_RGB_COLOR_GREEN2 vigra::RGBValue( 0, 238, 0) #define VISUALIZE_RGB_COLOR_GREEN3 vigra::RGBValue( 0, 205, 0) #define VISUALIZE_RGB_COLOR_GREEN4 vigra::RGBValue( 0, 139, 0) #define VISUALIZE_RGB_COLOR_MAGENTA1 vigra::RGBValue(255, 0, 255) #define VISUALIZE_RGB_COLOR_MAGENTA2 vigra::RGBValue(238, 0, 238) #define VISUALIZE_RGB_COLOR_MAGENTA3 vigra::RGBValue(205, 0, 205) #define VISUALIZE_RGB_COLOR_MAGENTA4 vigra::RGBValue(139, 0, 139) #define VISUALIZE_RGB_COLOR_ORANGE1 vigra::RGBValue(255, 165, 0) #define VISUALIZE_RGB_COLOR_ORANGE2 vigra::RGBValue(238, 154, 0) #define VISUALIZE_RGB_COLOR_ORANGE3 vigra::RGBValue(205, 133, 0) #define VISUALIZE_RGB_COLOR_ORANGE4 vigra::RGBValue(139, 90, 0) #define VISUALIZE_RGB_COLOR_RED1 vigra::RGBValue(255, 0, 0) #define VISUALIZE_RGB_COLOR_RED2 vigra::RGBValue(238, 0, 0) #define VISUALIZE_RGB_COLOR_RED3 vigra::RGBValue(205, 0, 0) #define VISUALIZE_RGB_COLOR_RED4 vigra::RGBValue(139, 0, 0) #define VISUALIZE_RGB_COLOR_YELLOW1 vigra::RGBValue(255, 255, 0) #define VISUALIZE_RGB_COLOR_YELLOW2 vigra::RGBValue(238, 238, 0) #define VISUALIZE_RGB_COLOR_YELLOW3 vigra::RGBValue(205, 205, 0) #define VISUALIZE_RGB_COLOR_YELLOW4 vigra::RGBValue(139, 139, 0) // Different marker types offered by visualizePoint() typedef enum { NO_MARKER, DOT_MARKER, PLUS_MARKER, CROSS_MARKER, HOLLOW_SQUARE_MARKER, HOLLOW_DIAMOND_MARKER, } marker_t; //< visualize-movable-point light orange #define VISUALIZE_MOVABLE_POINT VISUALIZE_RGB_COLOR_ORANGE1 //< mark-movable-point diamond #define MARK_MOVABLE_POINT HOLLOW_DIAMOND_MARKER //< visualize-frozen-point bright white #define VISUALIZE_FROZEN_POINT VISUALIZE_RGB_COLOR_GRAY255 //< mark-frozen-point cross #define MARK_FROZEN_POINT CROSS_MARKER //< visualize-initial-path-color dark yellow #define VISUALIZE_INITIAL_PATH VISUALIZE_RGB_COLOR_YELLOW4 //< visualize-short-path-value-color bright yellow #define VISUALIZE_SHORT_PATH_VALUE VISUALIZE_RGB_COLOR_YELLOW1 //< visualize-first-vertex-value-color medium green #define VISUALIZE_FIRST_VERTEX_VALUE VISUALIZE_RGB_COLOR_GREEN3 //< visualize-next-vertex-value-color light green #define VISUALIZE_NEXT_VERTEX_VALUE VISUALIZE_RGB_COLOR_GREEN2 //< visualize-no-overlap-value-color dark red #define VISUALIZE_NO_OVERLAP_VALUE VISUALIZE_RGB_COLOR_RED4 //< visualize-state-space-color dark blue #define VISUALIZE_STATE_SPACE VISUALIZE_RGB_COLOR_BLUE3 //< visualize-state-space-inside-color bright cyan #define VISUALIZE_STATE_SPACE_INSIDE VISUALIZE_RGB_COLOR_CYAN1 //< visualize-state-space-unconverged-color bright magenta #define VISUALIZE_STATE_SPACE_UNCONVERGED VISUALIZE_RGB_COLOR_MAGENTA1 // For CIELAB, CIELUV, and CIECAM blending, Enblend and Enfuse // transform the input images from their respective RGB color spaces // to XYZ space (and for CIECAM then on to JCh). The following two // #defines control the color transformation from and to XYZ space. #define RENDERING_INTENT_FOR_BLENDING INTENT_PERCEPTUAL #define TRANSFORMATION_FLAGS_FOR_BLENDING cmsFLAGS_NOCACHE // Select our preferred type of image depending on what ./configure // tells us. #ifdef CACHE_IMAGES #error "The ImageCache feature has been withdrawn. Reconfigure without ImageCache and re-build." #define IMAGETYPE vigra_ext::CachedFileImage #else #define IMAGETYPE vigra::BasicImage #endif #ifdef WIN32 #define sleep(m_duration) Sleep(m_duration) #endif #if defined __MINGW32__ || defined __MINGW64__ #undef rand_r #undef strtok_r #endif #define PENALIZE_DEPRECATED_OPTION(m_old_name, m_new_name) \ do { \ std::cerr << command << \ ": info: option \"" m_old_name "\" is deprecated; use \"" m_new_name "\" instead" << \ std::endl; \ sleep(1); \ } while (false) #define lengthof(m_array) (sizeof(m_array) / sizeof(m_array[0])) // Replacement for `assert(0)' and `assert(false)'. class never_reached : public std::runtime_error { public: never_reached() = delete; explicit never_reached(const std::string& a_message) : std::runtime_error(a_message) {} virtual ~never_reached() noexcept {} }; #ifdef __GNUC__ #define NEVER_REACHED(m_message) \ do {__builtin_unreachable(); throw ::never_reached(m_message);} while (false) #else #define NEVER_REACHED(m_message) throw ::never_reached(m_message) #endif namespace enblend { /** The different image overlap classifications. */ enum Overlap {NoOverlap, PartialOverlap, CompleteOverlap}; /** Symbolic expressions for the three different metrics that * vigra::distanceTransform understands. */ typedef enum { ChessboardDistance, // 0 ManhattanDistance, // 1, L1 norm EuclideanDistance // 2, L2 norm } nearest_neighbor_metric_t; /** Define our own reentrant, uniform pseudo-random number generator. */ inline int rand_r(unsigned int* seed) { *seed = *seed * 1103515245U + 12345U; return static_cast(*seed % (static_cast(RAND_MAX) + 1U)); } /** Answer the square of the argument x. */ template inline t square(t x) { return x * x; } /** Test whether s starts with p. */ inline static bool starts_with(const std::string& s, const std::string& p) { return s.substr(0U, p.length()) == p; } /** Answer the string representation of the boolean b. */ std::string stringOfBool(bool b) { return b ? "true" : "false"; } /** Answer whether we can open aFilename. */ bool can_open_file(const std::string& aFilename) { errno = 0; std::ifstream file(aFilename.c_str()); if (!file) { std::cerr << command << ": failed to open \"" << aFilename << "\": " << errorMessage(errno) << "\n"; return false; } else { errno = 0; file.close(); if (file.fail()) { std::cerr << command << ": info: problems when closing \"" << aFilename << "\": " << errorMessage(errno) << "\n"; } return true; } } /** Answer the VIGRA file type as determined by the extension of * aFileName. */ std::string getFileType(const std::string& aFileName) { const std::string ext(to_upper_copy(aFileName.substr(aFileName.rfind(".") + 1U))); if (ext == "JPG") return "JPEG"; else if (ext == "TIF") return "TIFF"; else if (ext == "VIF") return "VIFF"; else if (ext == "PBM" || ext == "PGM" || ext == "PPM") return "PNM"; else return ext; } /** Convert aWraparoundMode given as string to the internal * representation as enum. */ boundary_t wraparoundOfString(const char* aWraparoundMode) { const std::string mode(to_upper_copy(std::string(aWraparoundMode))); if (mode == "NONE" || mode == "OPEN") return OpenBoundaries; else if (mode == "HORIZONTAL") return HorizontalStrip; else if (mode == "VERTICAL") return VerticalStrip; else if (mode == "BOTH" || mode == "HORIZONTAL+VERTICAL" || mode == "VERTICAL+HORIZONTAL") return DoubleStrip; else return UnknownWrapAround; } /** Convert aBoundaryMode to its string representation. */ std::string stringOfWraparound(boundary_t aBoundaryMode) { switch (aBoundaryMode) { case OpenBoundaries: return "none"; case HorizontalStrip: return "horizontal"; case VerticalStrip: return "vertical"; case DoubleStrip: return "both"; default: NEVER_REACHED("switch control expression \"aBoundaryMode\" out of range"); } } /** Convert a_string into a number. * * Perform two validating tests in the numerical result. These are, * for example, tests for lower and upper boundaries. */ template NumericType numberOfString(const char* a_string, // string we want to convert into a number Validator1 is_valid1, // 1st validator function const std::string& invalid_message1, // error message for failed 1st validation NumericType replacement_value1, // replacement return value on 1st failure Validator2 is_valid2, // 2nd validator function const std::string& invalid_message2, // error message for failed 2nd validation NumericType replacement_value2) // replacement return value on 2nd failure { typedef std::numeric_limits traits; char* tail; long int long_int_value; double double_value; NumericType value; errno = 0; if (traits::is_exact) { long_int_value = strtol(a_string, &tail, 10); } else { double_value = strtod(a_string, &tail); } if (errno != 0) { std::cerr << command << ": " << "illegal numeric format of \"" << a_string << "\": " << errorMessage(errno) << std::endl; exit(1); } if (*tail != 0) { if (strcmp(a_string, tail) == 0) { std::cerr << command << ": " << "number is garbage; maybe the option before \"" << a_string << "\" needs an argument" << std::endl; } else { std::cerr << command << ": " << "trailing garbage \"" << tail << "\" in \"" << a_string << "\"" << std::endl; } exit(1); } if (traits::is_exact) { if (traits::is_signed) { if (long_int_value < traits::min() || long_int_value > traits::max()) { std::cerr << command << ": " << "signed number x = " << long_int_value << " out of range " << traits::min() << " <= x <= " << traits::max() << std::endl; exit(1); } else { value = static_cast(long_int_value); } } else { if (long_int_value < 0L || long_int_value > traits::max()) { std::cerr << command << ": " << "unsigned number x = " << long_int_value << " out of range 0 <= x <= " << traits::max() << std::endl; exit(1); } else { value = static_cast(long_int_value); } } } else { value = static_cast(double_value); } if (is_valid1(value)) { if (is_valid2(value)) { return value; } else { std::cerr << command << ": warning: " << invalid_message2 << std::endl; return replacement_value2; } } else { std::cerr << command << ": warning: " << invalid_message1 << std::endl; return replacement_value1; } } template NumericType numberOfString(const std::string& a_string, // string we want to convert into a number Validator1 is_valid1, // 1st validator function const std::string& invalid_message1, // error message for failed 1st validation NumericType replacement_value1, // replacement return value on 1st failure Validator2 is_valid2, // 2nd validator function const std::string& invalid_message2, // error message for failed 2nd validation NumericType replacement_value2) // replacement return value on 2nd failure { numberOfString(&a_string[0], is_valid1, invalid_message1, replacement_value1, is_valid2, invalid_message2, replacement_value2); } /** Convert a_string into a number. */ template NumericType numberOfString(const char* a_string, // string we want to convert into a number Validator is_valid, // validator function const std::string& invalid_message, // error message for failed validation NumericType replacement_value) // replacement return value on failure { return numberOfString(a_string, is_valid, invalid_message, replacement_value, [](NumericType) {return true;}, "", NumericType()); } template NumericType numberOfString(const std::string& a_string, // string we want to convert into a number Validator is_valid, // validator function const std::string& invalid_message, // error message for failed validation NumericType replacement_value) // replacement return value on failure { return numberOfString(&a_string[0], is_valid, invalid_message, replacement_value); } inline bool isFloatingPoint(const std::string& aPixelType) { return aPixelType == "FLOAT" || aPixelType == "DOUBLE"; } /** Convert an anOutputDepth to a "pixel type" string understood by * VIGRA. */ std::string outputPixelTypeOfString(const char* anOutputDepth) { typedef std::map Str2StrMapType; Str2StrMapType depthMap = { {"INT16", "INT16"}, {"INT32", "INT32"}, {"8", "UINT8"}, {"16", "UINT16"}, {"32", "UINT32"}, {"UINT8", "UINT8"}, {"UINT16", "UINT16"}, {"UINT32", "UINT32"}, {"DOUBLE", "DOUBLE"}, {"FLOAT", "FLOAT"}, {"R32", "FLOAT"}, {"R64", "DOUBLE"}, {"REAL32", "FLOAT"}, {"REAL64", "DOUBLE"} }; const std::string output_depth(to_upper_copy(std::string(anOutputDepth))); Str2StrMapType::const_iterator p = depthMap.find(output_depth); if (p == depthMap.end()) { throw std::invalid_argument(std::string("unknown output depth \"") + anOutputDepth + "\""); } else { return p->second; } } /** Answer the best pixel type of an image given aFileType with * respect to aPixelType. This is the type with the largest range. */ std::string bestPixelType(const std::string& aFileType, const std::string& aPixelType) { if (aFileType == "BMP" || aFileType == "JPEG" || aFileType == "RAS") { return "UINT8"; } else if (aFileType == "PNG" && (aPixelType == "INT32" || aPixelType == "UINT32" || aPixelType == "FLOAT" || aPixelType == "DOUBLE")) { return "UINT16"; } else if (aFileType == "EXR") { return "FLOAT"; } else { return aPixelType; } } typedef std::pair range_t; /** Answer the maximum range of values aPixelType can represent. */ range_t rangeOfPixelType(const std::string& aPixelType) { typedef std::map Str2PairMapType; Str2PairMapType rangeMap = { {"INT8", std::make_pair(vigra::NumericTraits::min(), vigra::NumericTraits::max())}, {"INT16", std::make_pair(vigra::NumericTraits::min(), vigra::NumericTraits::max())}, {"INT32", std::make_pair(vigra::NumericTraits::min(), vigra::NumericTraits::max())}, {"UINT8", std::make_pair(0.0, vigra::NumericTraits::max())}, {"UINT16", std::make_pair(0.0, vigra::NumericTraits::max())}, {"UINT32", std::make_pair(0.0, vigra::NumericTraits::max())}, {"FLOAT", std::make_pair(0.0, 1.0)}, {"DOUBLE", std::make_pair(0.0, 1.0)} }; assert(!aPixelType.empty()); Str2PairMapType::const_iterator r = rangeMap.find(aPixelType); if (r == rangeMap.end()) { throw std::invalid_argument(std::string("unknown pixel type \"") + aPixelType + "\""); } else { return r->second; } } /** Answer whether aPixelType defines a range that is so larges that * it includes both aRange and anotherRange. */ bool includesBothRanges(const std::string& aPixelType, const range_t& aRange, const range_t& anotherRange) { const range_t range = rangeOfPixelType(aPixelType); return (aRange.first >= range.first && aRange.second <= range.second && anotherRange.first >= range.first && anotherRange.second <= range.second); } /** Answer the smallest pixel type that is larger or equal to both * aPixelType and anotherPixelType. */ std::string maxPixelType(const std::string& aPixelType, const std::string& anotherPixelType) { const range_t range1 = rangeOfPixelType(aPixelType); const range_t range2 = rangeOfPixelType(anotherPixelType); if (aPixelType == "DOUBLE" || anotherPixelType == "DOUBLE") { return "DOUBLE"; } else if (aPixelType == "FLOAT" || anotherPixelType == "FLOAT") { return "FLOAT"; } else if (range1.first <= range2.first && range1.second >= range2.second) { return aPixelType; // first includes second } else if (range2.first <= range1.first && range2.second >= range1.second) { return anotherPixelType; // second includes first } else { // Types are different: look for the smallest containing type typedef std::vector string_array; typedef string_array::const_iterator string_array_ci; if (range1.first < 0 || range2.first < 0) { const string_array types = {"INT8", "INT16", "INT32"}; for (string_array_ci i = types.begin(); i != types.end(); ++i) { if (includesBothRanges(*i, range1, range2)) { return *i; } } return "INT32"; } else { const string_array types = {"UINT8", "UINT16", "UINT32"}; for (string_array_ci i = types.begin(); i != types.end(); ++i) { if (includesBothRanges(*i, range1, range2)) { return *i; } } return "UINT32"; } } } /** Answer the sign of x. */ template inline int sign(T x) { return x > T() ? 1 : (x < T() ? -1 : 0); } /** Compute the integral logarithm of n to the base 10. We do not * need to take special care of the case n == 0 for our purposes. */ inline unsigned ilog10(unsigned n) { return n <= 9 ? 0 : 1 + ilog10(n / 10); } /** Expand aTemplate filling the variable parts with anInputFilename, * anOutputFilename, and aNumber depending on the conversion * specifiers in aTemplate. * * Conversion Specifiers - lowercase characters refer to * anInputFilename whereas uppercase ones refer to anOutputFilename: * %% A single '%'-sign * %i aNumber unaltered * %n successor of aNumber * %p aFilename unaltered * %d directory part of aFilename * %b non-directory part (aka basename) of aFilename * %f basename of aFilename without extension * %e extension of aFilename (including the leading dot) * All other characters in aTemplate are passed through literally. * * The "%i" and "%n" conversions honor a flag which is either * '0' pad with zeros (default) or * PUNCT i.e. any punctuation character to pad with * and a width specification. If no width is requested, the * width is computed based on aNumberOfImages. * * For example * expandFilenameTemplate("mask-%04n.tif", 2, "foobar.jpg", 9) * evaluates to * mask-0009.tif */ std::string expandFilenameTemplate(const std::string& aTemplate, unsigned aNumberOfImages, const std::string& anInputFilename, const std::string& anOutputFilename, unsigned aNumber) { std::string result; for (std::string::const_iterator c = aTemplate.begin(); c != aTemplate.end(); ++c) { if (*c == '%') { ++c; if (c == aTemplate.end()) { result.push_back(*c); } else { char pad = 0; while (c != aTemplate.end() && (*c == '0' || ispunct(*c))) { pad = *c; ++c; } std::string width; while (c != aTemplate.end() && isdigit(*c)) { width.push_back(*c); ++c; } if (c != aTemplate.end()) { switch (*c) { case '%': result.push_back(*c); break; case 'n': ++aNumber; ++aNumberOfImages; BOOST_FALLTHROUGH; case 'i': { std::ostringstream oss; oss << std::setw(width.empty() ? 1U + ilog10(aNumberOfImages - 1U) : atoi(width.c_str())) << std::setfill(pad == 0 ? '0' : pad) << aNumber; result.append(oss.str()); break; } case 'P': result.append(anOutputFilename); break; case 'p': result.append(anInputFilename); break; case 'D': result.append(extractDirname(anOutputFilename)); break; case 'd': result.append(extractDirname(anInputFilename)); break; case 'B': result.append(extractBasename(anOutputFilename)); break; case 'b': result.append(extractBasename(anInputFilename)); break; case 'F': result.append(extractFilename(anOutputFilename)); break; case 'f': result.append(extractFilename(anInputFilename)); break; case 'E': result.append(extractExtension(anOutputFilename)); break; case 'e': result.append(extractExtension(anInputFilename)); break; default: std::cerr << command << ": warning: ignoring unknown variable character "; if (isprint(*c)) { std::cerr << "'" << *c << "'"; } else { std::cerr << "0x" << std::hex << *c; } std::cerr << " in\n" << command << ": warning: filename template \"" << aTemplate << "\"" << std::endl; } // switch (*c) } } } else { result.push_back(*c); } } return result; } /** Answer a phrase that describes a layer in an image consisting of * multiple layers. If the image has got only one layer, we avoid to * confuse the user and answer an empty string. */ inline std::string optional_layer_name(unsigned layer_number, unsigned layer_total) { if (layer_total <= 1U) { return std::string(); } else { std::ostringstream oss; oss << ", layer " << layer_number << "/" << layer_total; return oss.str(); } } template inline static void trim_if(std::string& a_string, predicate a_predicate) { auto negated_predicate = std::bind(std::logical_not(), std::bind(a_predicate, std::placeholders::_1)); std::string::iterator begin = std::find_if(a_string.begin(), a_string.end(), negated_predicate); if (begin == a_string.end()) { a_string.clear(); } else { std::string::reverse_iterator reverse_end = std::find_if(a_string.rbegin(), a_string.rend(), negated_predicate); a_string.assign(begin, reverse_end.base()); } } inline std::string profileInfo(cmsHPROFILE profile, cmsInfoType info) { const size_t size = cmsGetProfileInfoASCII(profile, info, cmsNoLanguage, cmsNoCountry, nullptr, 0); std::string information(size, '\000'); cmsGetProfileInfoASCII(profile, info, cmsNoLanguage, cmsNoCountry, &information[0], size); trim_if(information, std::bind(std::less_equal(), std::placeholders::_1, '\040')); return information; } inline std::string profileDescription(cmsHPROFILE profile) { return profileInfo(profile, cmsInfoDescription); } inline std::string profileName(cmsHPROFILE profile) { return profileInfo(profile, cmsInfoModel); } inline unsigned profileChannels(cmsHPROFILE profile) { const cmsColorSpaceSignature signature = cmsGetColorSpace(profile); const unsigned number_of_channels = cmsChannelsOf(signature); assert(number_of_channels == 1U || number_of_channels == 3U); return number_of_channels; } } // namespace enblend #ifndef HAVE_STRTOK_R char* strtok_r(char* str, const char* delim, char** save_ptr) { char *s = str ? str : *save_ptr; if (s) { while (*s != 0 && strchr(delim, (int) *s)) { s++; } if (*s) { char *token = s; while (*s != 0 && !strchr(delim, (int) *s)) { s++; } if (*s) { *s = 0; s++; } *save_ptr = s; return token; } else { return nullptr; } } else { return nullptr; } } #endif #endif /* __COMMON_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/gen_sig0000644000175000017500000000667012321255011013320 00000000000000#! /usr/bin/env perl # name: gen_sig # synopsis: generate signature in Harry-van-der-Wolf style # author: Dr. Christoph L. Spiel # perl version: 5.10.0 # This file is part of Enblend. # Licence details can be found in the file COPYING. use strict; use warnings; use Sig; sub octalize_string { my ($string, $prefix) = @_; $prefix = '' unless $prefix; my $result; my $max_chars = 8; my $length = length $string; for (my $i = 1; $i <= $length; $i++) { $result .= sprintf "\\%03o", ord(substr $string, $i - 1, 1); if ($i % $max_chars == 0 and $i != $length) { $result .= qq("\n $prefix"); } } return qq($prefix"$result"); } sub emit_class { my ($signature, $checksum, $extra_checksum) = @_; print < extern const std::string command; class Signature { public: Signature(): checksum_(@{[sprintf "0%011o", $checksum]}U), neg_checksum_(0U) {} const wchar_t* message() const { return @{[octalize_string($signature, q(L))]}; } void initialize() { #ifdef DEBUG_FORCE_SIGNATURE_CHECK_FAILURE checksum_++; neg_checksum_ = checksum_; #else neg_checksum_ = ~checksum_; #endif } void check() const { #ifdef DEBUG_SIGNATURE_CHECK if (checksum_ != ~neg_checksum_) { std::cerr << "+ static checksum " << checksum_ << " does not match static shadow checksum " << ~neg_checksum_ << "\\n"; } if (generate_checksum() != checksum_) { std::cerr << "+ dynamic checksum " << generate_checksum() << " does not match static checksum " << checksum_ << ", where\\n" << "+ message is <" << message() << ">\\n"; } #endif if (generate_checksum() != checksum_ || checksum_ != ~neg_checksum_) { std::cerr << command.c_str(); // MSVC chokes without c_str() #ifdef WANT_AGGRESSIVE_SIGNATURE_CHECK std::cerr << @{[octalize_string(qq(: tampered binary\n))]}; exit(1); #else std::cerr << @{[octalize_string(qq(: warning: signature check failed\n))]}; #endif } } unsigned generate_checksum() const { const wchar_t* m = message(); return m == nullptr ? 0U : std::accumulate(m, m + wcslen(m), 0U) & 037777777777U; } private: unsigned checksum_; unsigned neg_checksum_; }; #endif // SIGNATURE_H_INCLUDED_ END_OF_CLASS } sub self_test { my $sig = Sig->new(); my $ok = 1; print "// self-test...\n"; unless ($sig->get_username()) { print "// no user name\n"; $ok = 0; } unless ($sig->get_hostname()) { print "// no hostname\n"; $ok = 0; } unless ($sig->get_date()) { print "// no date\n"; $ok = 0; } unless ($sig->get_time()) { print "// no time\n"; $ok = 0; } print "// ", $sig->signature(), "\n"; print "// passed\n" if $ok; } sub main { if ($ARGV[0] and $ARGV[0] =~ m/--extra=(.*)/) { my $sig = Sig->new(); emit_class($sig->signature(), unpack("%32C*", $sig->signature()), unpack("%32C*", $1)); } else { self_test(); } } main(); enblend-enfuse-4.2/src/functoraccessor.hxx0000644000175000017500000004201212641704341015716 00000000000000// -*- c-basic-offset: 4 -*- /** @file functoraccessor.hxx * * @author Pablo d'Angelo * * $Id: FunctorAccessor.h,v 1.5 2007/01/27 05:00:35 acmihal Exp $ * * This 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 software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef FUNCTORACCESSOR_HXX_ #define FUNCTORACCESSOR_HXX_ #include namespace vigra_ext { /** This class can be used to apply a function when reading the input image. Can be used to apply point operations temporarily, like scaling, gamma correction etc. This is a read only accessor, writing is not supported. */ template class ReadFunctorAccessor { public: typedef typename Functor::result_type value_type; ReadFunctorAccessor(Functor f, Accessor a) : m_f(f), m_a(a) { } /** Get functor result template void function(A a, B b) { }; */ template typename Functor::result_type operator()(ITERATOR_ const & i, DIFFERENCE_ d) const { return m_f(m_a(i,d)); } /** Get functor result */ template typename Functor::result_type operator()(ITERATOR const & i) const { return m_f(m_a(i)); } protected: Functor m_f; Accessor m_a; }; /** This class can be used to apply a function when writing to an image Can be used to apply point operations temporarily, like scaling, gamma correction etc. This is a write only accessor, reading is not supported. */ template class WriteFunctorAccessor { public: typedef typename Functor::result_type value_type; WriteFunctorAccessor(Functor f, Accessor a) : m_f(f), m_a(a) { } /** Set functor result */ template void set(Value const & v, ITERATOR const & i) const { m_a.set(m_f(vigra::detail::RequiresExplicitCast::cast(v)), i); } /** Set functor result */ template void set(Value const & v, ITERATOR_ const & i, DIFFERENCE_ d) const { m_a.set(m_f(vigra::detail::RequiresExplicitCast::cast(v)),i,d); } Functor m_f; Accessor m_a; }; /** define a write only accessor for a virtual Image, 2> image, which actually consists of two Images. Useful to split an image into gray and alpha images while loading, like it is shown in the following example: \code vigra::ImageImportInfo info(argv[1]); if(info.numBands() == 2 && info.numExtraBands() == 1) { vigra::BImage image; vigra::BImage mask; image.resize(info.width(), info.height()); mask.resize(info.width(), info.height()); // construct special reading accessor, to split // the image into two images while reading vigra_ext::SplitVector2Accessor splitA(image.upperLeft(), image.accessor(), mask.upperLeft(), mask.accessor()); importImage(info, Diff2D(), splitA ); \endcode */ template class SplitVector2Accessor { public: /** the vector's value_type */ typedef vigra::TinyVector value_type; typedef typename value_type::value_type component_type; /** Construct from two image iterators and associated accessors. */ SplitVector2Accessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2) : i1_(i1), a1_(a1), i2_(i2), a2_(a2) {} /** scalar & scalar image */ template void setComponent( V const & value, ITERATOR const & i, int idx ) const { switch (idx) { case 0: a1_.set(value, i1_, *i); break; case 1: a2_.set(value, i2_, *i); break; default: vigra_fail("too many components in input value"); } } /** return the size (Number of Bands) */ template unsigned int size(ITERATOR const & i) const { return 2; } Iter1 i1_; Acc1 a1_; Iter2 i2_; Acc2 a2_; }; /** split a vector image into a vector and a scalar image * * like SplitVector2Accessor, but for the vector -> vector, scalar * case. * * the template parameter SIZE gives the length of each vector * in the input image. components 0..SIZE-2, are put into the * image 1 (must be a vector image), and component SIZE-1 * is stored in image 2 (should be a scalar image) */ template class SplitVectorNAccessor { public: /** the vector's value_type */ typedef vigra::TinyVector value_type; typedef typename value_type::value_type component_type; /** Construct from two image iterators and associated accessors. */ SplitVectorNAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2) : i1_(i1), a1_(a1), i2_(i2), a2_(a2) {} /** vector & scalar image */ template void setComponent( V const & value, ITERATOR const & i, int idx ) const { if ( idx < SIZE - 1 ) { a1_.setComponent(value, i1_, *i, idx); } else if ( idx == SIZE - 1 ) { a2_.set(value, i2_, *i); } else { vigra_fail("too many components in input value"); } } /** return the size (Number of Bands) */ template unsigned int size(ITERATOR const & i) const { return SIZE; } Iter1 i1_; Acc1 a1_; Iter2 i2_; Acc2 a2_; }; /** merge two scalar images into a vector image. * * the inverse to SplitVector2Accessor. * */ template class MergeScalarScalar2VectorAccessor { public: /** the vector's value_type */ typedef vigra::TinyVector value_type; typedef typename value_type::value_type component_type; /** Construct from two image iterators and associated accessors. */ MergeScalarScalar2VectorAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2) : i1_(i1), a1_(a1), i2_(i2), a2_(a2) {} /** read the current data item */ template value_type operator()(DIFFERENCE_ const & d) const { return value_type(a1_(i1_, d), a2_(i2_, d)); } /** read one component */ template component_type getComponent(ITERATOR const & i, int idx) const { switch (idx) { case 0: return a1_( i1_, *i ); case 1: return a2_( i2_, *i ); default: vigra_fail("too many components in input value"); // never reached, but here to silence compiler exit(1); } } /** read one component, with offset */ template component_type const & getComponent(ITERATOR const & i, DIFFERENCE_ const & d, int idx) const { i += d; switch (idx) { case 0: return a1_.getComponent(i1_, *i, idx); case 1: return a2_.getComponent(i2_, *i, idx); default: vigra_fail("too many components in input value"); } } /** return the size (Number of Bands) */ template unsigned int size(ITERATOR const & i) const { return 2; } Iter1 i1_; Acc1 a1_; Iter2 i2_; Acc2 a2_; }; /** merge a vector and a scalar image into a vector image. * * This virtually "appends" the scalar image plane to * the vector image. * * the inverse to SplitVectorNAccessor. * */ template class MergeVectorScalar2VectorAccessor { public: /** the vector's value_type */ typedef typename Acc1::value_type image1_type; typedef typename Acc2::value_type image2_type; typedef typename image1_type::value_type component_type; typedef vigra::TinyVector value_type; /** Construct from two image iterators and associated accessors. */ MergeVectorScalar2VectorAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2) : i1_(i1), a1_(a1), i2_(i2), a2_(a2) {} /** read the current data item */ template value_type operator()(DIFFERENCE_ const & d) const { value_type ret; typename value_type::iterator it = ret.begin(); const image1_type & i1 = a1_(i1_, d); for ( typename image1_type::const_iterator it1 = i1.begin(); it1 != i1.end(); ++it1 ) { *it = *it1; it++; } *it = a2_(i2_, d); return ret; } /** read one component */ template component_type getComponent(ITERATOR const & i, int idx) const { if ( idx < SIZE - 1 ) { return a1_.getComponent(i1_, *i, idx); } else if ( idx == SIZE - 1 ) { return a2_(i2_, *i); } else { vigra_fail("too many components in input value"); // just to silence the compiler warning. this is // never reached, since vigra_fail will always // throw an exception. throw 0; } } /** read one component, with offset */ template component_type const getComponent(ITERATOR i, DIFFERENCE_ const & d, int idx) const { i += d; if ( idx < SIZE - 1 ) { return a1_.getComponent(i1_, *i, idx); } else if ( idx == SIZE - 1 ) { return a2_(i2_, *i); } else { vigra_fail("too many components in input value"); // just to silence the compiler warning. this is // never reached, since vigra_fail will always // throw an exception. throw 0; } } /** return the size (Number of Bands) */ template unsigned int size(ITERATOR const & i) const { return SIZE; } Iter1 i1_; Acc1 a1_; Iter2 i2_; Acc2 a2_; }; /** An accessor to encapsulate write access to a multiband image, and move divide it into two images. This is particulary useful, if a multiband image should be splitted into separate images during import operations. Then one doesn't need to create a temporary image. This can be used to copy a 4 band image into a 3 band image and a 1 band image, with a single copyImage, or during other operations. For example, some images contain an alpha channel, and depending on the application, this doesn't need to have the same type, for example, float RGB channels, uint8 mask channel. Many algorithms provided by vigra also expect the masks and the image in separate images. The following image combinations are supported so far: - vector -> scalar, scalar - vector -> vector, scalar This accessor is quite slow. It checks the vector indicies on every access. @bug This is not a complete accessor, only write operations are supported. @bug value_type is not specified correctly, I don't know how to merge them properly with template programming. Requirements: both images need to have the same elementary type */ template class ImageSplittingAccessor { public: /** value type of image 1 */ typedef typename Acc1::value_type image_type1; /** value type of image 2 */ typedef typename Acc2::value_type image_type2; /** @BUG: how to combine two value types into one? */ // typedef image_type1 value_type; /** Construct from two image iterators and associated accessors. */ ImageSplittingAccessor(Iter1 i1, Acc1 a1, Iter2 i2, Acc2 a2) : i1_(i1), a1_(a1), i2_(i2), a2_(a2) {} /** write value V into the two images. * * V has to be a stl compatible vector type, * the two images can be of vector or scalar types. * */ template void setComponent(V const & value, ITERATOR const & i, int idx) const { setComponentIsScalar(value, i, idx, vigra::NumericTraits::isScalar() ); } #if 0 /** Write the current data item. The type V must be a sequence type, Likewise the value types of image 1 and image 2. Its size must be size(image_type1) + size(image_type2); The type V of the passed in value is automatically converted to VALUETYPE. In case of a conversion floating point -> intergral this includes rounding and clipping. */ template void setVector2VectorVector(V const & value, ITERATOR const & i) const { // get pixels at current position indicated by iterator image_type1 & v1 = a1_(i); image_type2 & v2 = a2_(i2_, i - i1_); // TODO: check if the size of both images is correct // copy into first image typename V::iterator vIt = value.begin(); typename image_type1::iterator v1It = v1.begin(); while ( v1It != v1.end() && vIt != value.end()) { *v1It = detail::RequiresExplicitCast::cast(*vIt); ++v1It; ++vIt; } // copy rest into second image typename image_type2::iterator v2It = v2.begin(); while ( v2It != v1.end() && vIt != value.end()) { *v2It = detail::RequiresExplicitCast::cast(*vIt); ++v2It; ++vIt; } for (int i=0; i < value.size(); i++) { if (i < *i = detail::RequiresExplicitCast::cast(value); } /** Write the data item at an offset (can be 1D or 2D or higher order difference).. The type V of the passed in value is automatically converted to VALUETYPE. In case of a conversion floating point -> intergral this includes rounding and clipping. */ template void set(V const & value, ITERATOR const & i, DIFFERENCE_ const & diff) const { i[diff]= detail::RequiresExplicitCast::cast(value); } #endif protected: /** if first dest image is scalar */ template void setComponentIsScalar(V const & value, ITERATOR const & i, int idx, vigra::VigraTrueType) const { setComponentScalarIsScalar(value, i, idx, vigra::NumericTraits::isScalar() ); } /** if first dest image is vector image */ template void setComponentIsScalar(V const & value, ITERATOR const & i, int idx, vigra::VigraFalseType) const { setComponentVectorIsScalar(value, i, idx, vigra::NumericTraits::isScalar() ); } /** if scalar & scalar image */ template void setComponentScalarIsScalar(V const & value, ITERATOR const & i, int idx, vigra::VigraTrueType) const { switch (idx) { case 0: a1_.set(value, i); break; case 1: a2_.set(value, i2_, i - i1_); break; default: vigra_fail("too many components in input value"); } } /** if scalar & vector image */ template void setComponentScalarIsVector(V const & value, ITERATOR const & i, int idx, vigra::VigraTrueType) const { vigra_fail("vector -> scalar, vector accessor not implemented"); } /** if vector & scalar image */ template void setComponentVectorIsScalar(V const & value, ITERATOR const & i, int idx, vigra::VigraTrueType) const { image_type1 & v1 = a1_(i); typename image_type1::size_type s1 = v1.size(); if (idx < s1) { a1_.setComponent(value, i, idx); } else if ( idx == s1) { a2_.set(value, i2_, i - i1_); } else { vigra_fail("too many components in input value"); } } /** if vector & vector image */ template void setComponentVectorIsVector(V const & value, ITERATOR const & i, int idx, vigra::VigraTrueType) const { vigra_fail("vector -> vector, vector accessor not implemented"); } Iter1 i1_; Acc1 a1_; Iter2 i2_; Acc2 a2_; }; /** a sample functor that can be used to multiply pixel values with a constant*/ template struct Multiply { typedef T result_type; Multiply(T factor) : m_factor(factor) {} template PixelType operator()(PixelType const& v) const { return vigra::NumericTraits::fromRealPromote(v * m_factor); } T m_factor; }; } // namespace #endif // FUNCTORACCESSOR_HXX enblend-enfuse-4.2/src/introspection.cc0000644000175000017500000002250112674451053015177 00000000000000/* * Copyright (C) 2015, 2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include // GSL_VERSION #include // LCMS_VERSION #include // VIGRA_VERSION, impexListExtensions(), impexListFormats() #ifdef HAVE_CONFIG_H #include #endif #include "filespec.h" #include "global.h" #include "signature.h" #include "dynamic_loader.h" // HAVE_DYNAMICLOADER_IMPL #include "openmp_def.h" // OPENMP #include "opencl.h" // OPENCL #include "introspection.h" #ifdef _MSC_VER #include #endif extern const std::string command; extern Signature sig; extern int Verbose; namespace introspection { void printVersion(int argc, char** argv) { std::cout << command << " " << VERSION << "\n\n"; if (Verbose >= VERBOSE_VERSION_REPORTING) { #ifdef ENFUSE_SOURCE { std::cout << "Extra feature: dynamic linking support: " << #ifdef HAVE_DYNAMICLOADER_IMPL "yes" << #else "no" << #endif "\n"; } #endif // ENFUSE_SOURCE #ifdef CACHE_IMAGES std::cout << "Extra feature: image cache: yes\n"; { #ifdef WIN32 char lpPathBuffer[MAX_PATH]; const DWORD dwRetVal = GetTempPath(MAX_PATH, lpPathBuffer); if (dwRetVal <= MAX_PATH && dwRetVal != 0) { std::cout << " - cache file located in \"" << lpPathBuffer << "\"\n"; } #else const char* tmpdir = getenv("TMPDIR"); std::cout << " - environment variable TMPDIR "; if (tmpdir == nullptr) { std::cout << "not set, cache file in default directory \"/tmp\"\n"; } else { std::cout << "set, cache file located in \"" << tmpdir << "\"\n"; } #endif } #else std::cout << "Extra feature: image cache: no\n"; #endif #ifdef OPENMP const bool have_dynamic = have_openmp_dynamic(); std::cout << "Extra feature: OpenMP: yes\n" << " - version " << OPENMP_YEAR << '-' << OPENMP_MONTH << "\n" << " - " << (have_dynamic ? "" : "no ") << "support for dynamic adjustment of the number of threads;\n" << " dynamic adjustment " << (have_dynamic && omp_get_dynamic() ? "enabled" : "disabled") << " by default\n" << " - using " << omp_get_num_procs() << " processor" << (omp_get_num_procs() >= 2 ? "s" : "") << " and up to " << omp_get_max_threads() << " thread" << (omp_get_max_threads() >= 2 ? "s" : "") << "\n" << " - allocating thread-local dynamic memory with " << OMP_MALLOC_FUNCTIONS << "\n"; #else std::cout << "Extra feature: OpenMP: no\n"; #endif #ifdef OPENCL std::cout << "Extra feature: OpenCL: yes\n"; #ifdef _MSC_VER // catching errors with delay loading of opencl.dll // remember to reset __pfnDliFailureHook2 before // otherwise the failure hooks exits the program before __except is reached __try { ocl::print_opencl_information(); } __except(GetExceptionCode() == VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND) || GetExceptionCode() == VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND)) { std::cout << " but not available on this system\n"; } #else ocl::print_opencl_information(); #endif #else std::cout << "Extra feature: OpenCL: no\n"; #endif std::cout << "\n"; } std::cout << "Copyright (C) 2004-2009 Andrew Mihal.\n" << "Copyright (C) 2009-2016 Christoph Spiel.\n" << "\n" << "License GPLv2+: GNU GPL version 2 or later \n" << "This is free software: you are free to change and redistribute it.\n" << "There is NO WARRANTY, to the extent permitted by law.\n" << "\n" << "Written by Andrew Mihal, Christoph Spiel and others." << std::endl; exit(0); } // With the exception of TIFF, VIFF, PNG, and PNM all file types // store only 1 byte (gray scale and mapped RGB) or 3 bytes (RGB) // per pixel. // // PNG can store UInt8 and UInt16 values, and supports 1 and 3 // channel images. One additional alpha channel is also supported. // // PNM can store 1 and 3 channel images with UInt8, UInt16 and // UInt32 values in each channel. // // TIFF and VIFF are additionally able to store short and long // integers (2 or 4 bytes) and real values (32 bit float and 64 bit // double) without conversion. void printImageFormats() { std::string formats(vigra::impexListFormats()); std::string extensions(vigra::impexListExtensions()); const std::regex space(" "); const std::string replacement("\n "); formats = std::regex_replace(formats, space, replacement); extensions = std::regex_replace(extensions, space, replacement); std::cout << "Following image formats are supported by " << command << ":\n" << " " << formats << "\n" << "It automatically recognizes the image file extensions:\n" << " " << extensions << "\n" << "and -- where supported by the image format -- accepts per-channel depths:\n" << #ifndef DEBUG_8BIT_ONLY " " << "8 bits unsigned integral\n" << #endif " " << "16 bits unsigned or signed integral\n" << " " << "32 bits unsigned or signed integral\n" << " " << "32 bits floating-point\n" << " " << "64 bits floating-point\n" << std::endl; exit(0); } void printSignature() { std::cout.flush(); std::wcout << sig.message() << L"\n\n"; std::wcout.flush(); exit(0); } void printGlobbingAlgos() { const enblend::algorithm_list algos = enblend::known_globbing_algorithms(); std::cout << "Following globbing algorithms are supported:\n"; for (auto i = algos.begin(); i != algos.end(); ++i) { std::cout << " " << i->first << "\n" << " " << i->second << "\n"; } std::cout << std::endl; exit(0); } void printSoftwareComponents() { std::cout << "Compiler\n " << // IMPLEMENTATION NOTE: Order matters as both CLang and ICC // identify themselves as GCC, too. #if defined(__clang__) "clang++ " << __clang_major__ << '.' << __clang_minor__ << '.' << __clang_patchlevel__ << #elif defined(__ICC) || defined(__INTEL_COMPILER) "icpc " << __GNUC__ << '.' << __GNUC_MINOR__ << '.' << __GNUC_PATCHLEVEL__ << #elif defined(__GNUG__) "g++ " << __GNUC__ << '.' << __GNUC_MINOR__ << '.' << __GNUC_PATCHLEVEL__ << #elif defined(__IBMC__) || defined(__IBMCPP__) "xlc++ " << __IBMCPP__ << #elif defined(_MSC_VER) "MS Visual Studio " << _MSC_FULL_VER << #elif defined(__PGI) "pgcpp " << __PGIC__ << '.' << __PGIC_MINOR__ << '.' << __PGIC_PATCHLEVEL__ << #else "unknown" << #endif "\n" << #ifdef OPENMP " implementing OpenMP standard of " << _OPENMP / 100 << '-' << _OPENMP % 100 << "\n" << #endif "\n"; #ifdef OPENCL std::cout << "OpenCL APIs\n" << #ifdef CL_VERSION_1_0 " 1.0\n" << #endif #ifdef CL_VERSION_1_1 " 1.1\n" << #endif #ifdef CL_VERSION_1_2 " 1.2\n" << #endif #ifdef CL_VERSION_1_3 " 1.3\n" << #endif #ifdef CL_VERSION_2_0 " 2.0\n" << #endif #ifdef CL_VERSION_2_1 " 2.1\n" << #endif "\n"; #endif // OPENCL std::cout << "Libraries\n" << " GSL: " << GSL_VERSION << "\n" << //" JPEG: " << "\n" << " Little CMS: " << LCMS_VERSION / 1000 << '.' << (LCMS_VERSION / 10) % 100 << '.' << LCMS_VERSION % 10 << "\n" << //" PNG: " << "\n" << //" OpenEXR: " << "\n" << //" TIFF: " << "\n" << " Vigra: " << VIGRA_VERSION << "\n" << std::endl; exit(0); } } // end namespace introspection enblend-enfuse-4.2/src/Makefile.am0000644000175000017500000001016212635271573014030 00000000000000AM_CPPFLAGS = $(EXTRACPPFLAGS) AM_CFLAGS = $(EXTRACFLAGS) AM_CXXFLAGS = $(EXTRACXXFLAGS) AM_LDFLAGS = $(EXTRALDFLAGS) SUBDIRS = dynamic_loader layer_selection win32helpers bin_PROGRAMS = enblend enfuse enblend_SOURCES = fillpolygon.hxx functoraccessor.hxx rect2d.hxx stride.hxx \ \ anneal.h assemble.h blend.h bounds.h \ common.h enblend.h enblend.cc fixmath.h \ global.h graphcut.h \ maskcommon.h masktypedefs.h mask.h postoptimizer.h \ nearest.h numerictraits.h \ opencl.h opencl.cc opencl_anneal.h opencl_vigra.h \ openmp_def.h openmp_lock.h openmp_vigra.h \ path.h pyramid.h \ alternativepercentage.h alternativepercentage.cc \ error_message.h error_message.cc \ filenameparse.h filenameparse.cc \ filespec.h filespec.cc \ introspection.h introspection.cc \ mersenne.h mersenne.cc \ parameter.h parameter.cc \ self_test.h self_test.cc \ tiff_message.h tiff_message.cc \ timer.h timer.cc \ minimizer.h minimizer.cc \ muopt.h enblend_LDFLAGS = $(AM_LDFLAGS) enblend_LDADD = layer_selection/liblayersel.a \ $(GSL_LIBS) @EXTRA_LIBS@ enblend_CXXFLAGS = -DENBLEND_SOURCE $(AM_CXXFLAGS) $(GSL_CFLAGS) \ -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \ -I$(top_srcdir)/src/dynamic_loader \ -I$(top_srcdir)/src/layer_selection enfuse_SOURCES = functoraccessor.hxx rect2d.hxx stride.hxx \ \ assemble.h blend.h bounds.h common.h \ exposure_weight_base.h \ exposure_weight.h exposure_weight.cc \ enfuse.h enfuse.cc fixmath.h \ global.h mga.h numerictraits.h \ opencl.h opencl.cc opencl_vigra.h \ opencl_exposure_weight.h opencl_exposure_weight.cc \ openmp_def.h openmp_lock.h openmp_vigra.h \ pyramid.h \ alternativepercentage.h alternativepercentage.cc \ error_message.h error_message.cc \ filenameparse.h filenameparse.cc \ filespec.h filespec.cc \ introspection.h introspection.cc \ mersenne.h mersenne.cc \ parameter.h parameter.cc \ self_test.h self_test.cc \ tiff_message.h tiff_message.cc \ timer.h timer.cc \ minimizer.h minimizer.cc \ muopt.h enfuse_LDFLAGS = $(AM_LDFLAGS) enfuse_LDADD = dynamic_loader/libdynamic_loader.a \ layer_selection/liblayersel.a \ $(GSL_LIBS) @EXTRA_LIBS@ enfuse_CXXFLAGS = -DENFUSE_SOURCE $(AM_CXXFLAGS) $(GSL_CFLAGS) \ -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \ -I$(top_srcdir)/src/dynamic_loader \ -I$(top_srcdir)/src/layer_selection EXTRA_DIST = embrace calculate_state_probabilities.cl distance_transform_fh.cl \ enblend.1 enfuse.1 \ gen_sig DefaultSig.pm Sig.pm \ CMakeLists.txt DISTCLEANFILES = enblend.1 enfuse.1 # Generated sources BUILT_SOURCES = signature.h calculate_state_probabilities.icl distance_transform_fh.icl CLEANFILES = signature.h calculate_state_probabilities.icl distance_transform_fh.icl %.icl: %.cl $(AM_V_GEN)$(srcdir)/embrace --format=c++ --label=$(basename $(notdir $<))_source_code $< > $@ calculate_state_probabilities.icl: calculate_state_probabilities.cl distance_transform_fh.icl: distance_transform_fh.cl signature.h: $(srcdir)/gen_sig $(srcdir)/DefaultSig.pm $(srcdir)/Sig.pm @ $(PERL) -I$(srcdir) $< --extra=$(VERSION) > $@ # Documentation man_MANS = enblend.1 enfuse.1 #dist_man_MANS = enblend.1 enfuse.1 .PHONY: man man: enblend.1 enfuse.1 enblend.1: enblend $(AM_V_GEN)$(HELP2MAN) --no-info --output=$@ ./enblend enfuse.1: enfuse $(AM_V_GEN)$(HELP2MAN) --no-info --output=$@ ./enfuse enblend-enfuse-4.2/src/Makefile.in0000644000175000017500000025607412676432431014054 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = enblend$(EXEEXT) enfuse$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/_ac_latex_test.m4 \ $(top_srcdir)/m4/ac_latex_class.m4 \ $(top_srcdir)/m4/ac_latex_package.m4 \ $(top_srcdir)/m4/ac_prog_ar.m4 \ $(top_srcdir)/m4/ac_prog_latex.m4 \ $(top_srcdir)/m4/ac_type_sig_atomic_t.m4 \ $(top_srcdir)/m4/ax_boost_base.m4 \ $(top_srcdir)/m4/ax_cxx_as_const.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/ax_openmp.m4 \ $(top_srcdir)/m4/ax_prog_perl_modules.m4 \ $(top_srcdir)/m4/ax_with_prog.m4 $(top_srcdir)/m4/lrint.m4 \ $(top_srcdir)/m4/lrintf.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am_enblend_OBJECTS = enblend-enblend.$(OBJEXT) \ enblend-opencl.$(OBJEXT) \ enblend-alternativepercentage.$(OBJEXT) \ enblend-error_message.$(OBJEXT) \ enblend-filenameparse.$(OBJEXT) enblend-filespec.$(OBJEXT) \ enblend-introspection.$(OBJEXT) enblend-mersenne.$(OBJEXT) \ enblend-parameter.$(OBJEXT) enblend-self_test.$(OBJEXT) \ enblend-tiff_message.$(OBJEXT) enblend-timer.$(OBJEXT) \ enblend-minimizer.$(OBJEXT) enblend_OBJECTS = $(am_enblend_OBJECTS) enblend_DEPENDENCIES = layer_selection/liblayersel.a enblend_LINK = $(CXXLD) $(enblend_CXXFLAGS) $(CXXFLAGS) \ $(enblend_LDFLAGS) $(LDFLAGS) -o $@ am_enfuse_OBJECTS = enfuse-exposure_weight.$(OBJEXT) \ enfuse-enfuse.$(OBJEXT) enfuse-opencl.$(OBJEXT) \ enfuse-opencl_exposure_weight.$(OBJEXT) \ enfuse-alternativepercentage.$(OBJEXT) \ enfuse-error_message.$(OBJEXT) enfuse-filenameparse.$(OBJEXT) \ enfuse-filespec.$(OBJEXT) enfuse-introspection.$(OBJEXT) \ enfuse-mersenne.$(OBJEXT) enfuse-parameter.$(OBJEXT) \ enfuse-self_test.$(OBJEXT) enfuse-tiff_message.$(OBJEXT) \ enfuse-timer.$(OBJEXT) enfuse-minimizer.$(OBJEXT) enfuse_OBJECTS = $(am_enfuse_OBJECTS) enfuse_DEPENDENCIES = dynamic_loader/libdynamic_loader.a \ layer_selection/liblayersel.a enfuse_LINK = $(CXXLD) $(enfuse_CXXFLAGS) $(CXXFLAGS) \ $(enfuse_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(enblend_SOURCES) $(enfuse_SOURCES) DIST_SOURCES = $(enblend_SOURCES) $(enfuse_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONVERT = @CONVERT@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_IMPLEMENTATION = @DL_IMPLEMENTATION@ DOT = @DOT@ DVIPDF = @DVIPDF@ DVIPS = @DVIPS@ DYNAMIC_TEX_PREAMBLE = @DYNAMIC_TEX_PREAMBLE@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_LIBS = @EXTRA_LIBS@ GNUPLOT = @GNUPLOT@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_INLINE = @HAVE_INLINE@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LATEX = @LATEX@ LATEX2HTML = @LATEX2HTML@ LATEX2HTML_LIBDIR = @LATEX2HTML_LIBDIR@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ M4 = @M4@ MAKEINDEX = @MAKEINDEX@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ OPENEXR_LIBS = @OPENEXR_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SPLITHTML = @SPLITHTML@ STRIP = @STRIP@ SVGCONVERT = @SVGCONVERT@ TEXLOGANALYSER = @TEXLOGANALYSER@ VERSION = @VERSION@ VIGRAIMPEX_LIB = @VIGRAIMPEX_LIB@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ amsmath = @amsmath@ bindir = @bindir@ bold_extra = @bold_extra@ boretti_classesansparametre = @boretti_classesansparametre@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ color = @color@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enumitem = @enumitem@ exec_prefix = @exec_prefix@ float = @float@ footnote = @footnote@ graphicx = @graphicx@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hyperref = @hyperref@ hyphenat = @hyphenat@ ifpdf = @ifpdf@ includedir = @includedir@ index = @index@ infodir = @infodir@ install_sh = @install_sh@ latex = @latex@ latexsym = @latexsym@ libdir = @libdir@ libexecdir = @libexecdir@ listings = @listings@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ microtype = @microtype@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ ragged2e = @ragged2e@ refrep = @refrep@ report = @report@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shorttoc = @shorttoc@ srcdir = @srcdir@ suffix = @suffix@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ url = @url@ xstring = @xstring@ AM_CPPFLAGS = $(EXTRACPPFLAGS) AM_CFLAGS = $(EXTRACFLAGS) AM_CXXFLAGS = $(EXTRACXXFLAGS) AM_LDFLAGS = $(EXTRALDFLAGS) SUBDIRS = dynamic_loader layer_selection win32helpers enblend_SOURCES = fillpolygon.hxx functoraccessor.hxx rect2d.hxx stride.hxx \ \ anneal.h assemble.h blend.h bounds.h \ common.h enblend.h enblend.cc fixmath.h \ global.h graphcut.h \ maskcommon.h masktypedefs.h mask.h postoptimizer.h \ nearest.h numerictraits.h \ opencl.h opencl.cc opencl_anneal.h opencl_vigra.h \ openmp_def.h openmp_lock.h openmp_vigra.h \ path.h pyramid.h \ alternativepercentage.h alternativepercentage.cc \ error_message.h error_message.cc \ filenameparse.h filenameparse.cc \ filespec.h filespec.cc \ introspection.h introspection.cc \ mersenne.h mersenne.cc \ parameter.h parameter.cc \ self_test.h self_test.cc \ tiff_message.h tiff_message.cc \ timer.h timer.cc \ minimizer.h minimizer.cc \ muopt.h enblend_LDFLAGS = $(AM_LDFLAGS) enblend_LDADD = layer_selection/liblayersel.a \ $(GSL_LIBS) @EXTRA_LIBS@ enblend_CXXFLAGS = -DENBLEND_SOURCE $(AM_CXXFLAGS) $(GSL_CFLAGS) \ -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \ -I$(top_srcdir)/src/dynamic_loader \ -I$(top_srcdir)/src/layer_selection enfuse_SOURCES = functoraccessor.hxx rect2d.hxx stride.hxx \ \ assemble.h blend.h bounds.h common.h \ exposure_weight_base.h \ exposure_weight.h exposure_weight.cc \ enfuse.h enfuse.cc fixmath.h \ global.h mga.h numerictraits.h \ opencl.h opencl.cc opencl_vigra.h \ opencl_exposure_weight.h opencl_exposure_weight.cc \ openmp_def.h openmp_lock.h openmp_vigra.h \ pyramid.h \ alternativepercentage.h alternativepercentage.cc \ error_message.h error_message.cc \ filenameparse.h filenameparse.cc \ filespec.h filespec.cc \ introspection.h introspection.cc \ mersenne.h mersenne.cc \ parameter.h parameter.cc \ self_test.h self_test.cc \ tiff_message.h tiff_message.cc \ timer.h timer.cc \ minimizer.h minimizer.cc \ muopt.h enfuse_LDFLAGS = $(AM_LDFLAGS) enfuse_LDADD = dynamic_loader/libdynamic_loader.a \ layer_selection/liblayersel.a \ $(GSL_LIBS) @EXTRA_LIBS@ enfuse_CXXFLAGS = -DENFUSE_SOURCE $(AM_CXXFLAGS) $(GSL_CFLAGS) \ -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \ -I$(top_srcdir)/src/dynamic_loader \ -I$(top_srcdir)/src/layer_selection EXTRA_DIST = embrace calculate_state_probabilities.cl distance_transform_fh.cl \ enblend.1 enfuse.1 \ gen_sig DefaultSig.pm Sig.pm \ CMakeLists.txt DISTCLEANFILES = enblend.1 enfuse.1 # Generated sources BUILT_SOURCES = signature.h calculate_state_probabilities.icl distance_transform_fh.icl CLEANFILES = signature.h calculate_state_probabilities.icl distance_transform_fh.icl # Documentation man_MANS = enblend.1 enfuse.1 all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .cc .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) enblend$(EXEEXT): $(enblend_OBJECTS) $(enblend_DEPENDENCIES) $(EXTRA_enblend_DEPENDENCIES) @rm -f enblend$(EXEEXT) $(AM_V_CXXLD)$(enblend_LINK) $(enblend_OBJECTS) $(enblend_LDADD) $(LIBS) enfuse$(EXEEXT): $(enfuse_OBJECTS) $(enfuse_DEPENDENCIES) $(EXTRA_enfuse_DEPENDENCIES) @rm -f enfuse$(EXEEXT) $(AM_V_CXXLD)$(enfuse_LINK) $(enfuse_OBJECTS) $(enfuse_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-alternativepercentage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-enblend.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-error_message.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-filenameparse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-filespec.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-introspection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-mersenne.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-minimizer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-opencl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-parameter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-self_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-tiff_message.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enblend-timer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-alternativepercentage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-enfuse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-error_message.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-exposure_weight.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-filenameparse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-filespec.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-introspection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-mersenne.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-minimizer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-opencl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-opencl_exposure_weight.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-parameter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-self_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-tiff_message.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enfuse-timer.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` enblend-enblend.o: enblend.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-enblend.o -MD -MP -MF $(DEPDIR)/enblend-enblend.Tpo -c -o enblend-enblend.o `test -f 'enblend.cc' || echo '$(srcdir)/'`enblend.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-enblend.Tpo $(DEPDIR)/enblend-enblend.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='enblend.cc' object='enblend-enblend.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-enblend.o `test -f 'enblend.cc' || echo '$(srcdir)/'`enblend.cc enblend-enblend.obj: enblend.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-enblend.obj -MD -MP -MF $(DEPDIR)/enblend-enblend.Tpo -c -o enblend-enblend.obj `if test -f 'enblend.cc'; then $(CYGPATH_W) 'enblend.cc'; else $(CYGPATH_W) '$(srcdir)/enblend.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-enblend.Tpo $(DEPDIR)/enblend-enblend.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='enblend.cc' object='enblend-enblend.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-enblend.obj `if test -f 'enblend.cc'; then $(CYGPATH_W) 'enblend.cc'; else $(CYGPATH_W) '$(srcdir)/enblend.cc'; fi` enblend-opencl.o: opencl.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-opencl.o -MD -MP -MF $(DEPDIR)/enblend-opencl.Tpo -c -o enblend-opencl.o `test -f 'opencl.cc' || echo '$(srcdir)/'`opencl.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-opencl.Tpo $(DEPDIR)/enblend-opencl.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='opencl.cc' object='enblend-opencl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-opencl.o `test -f 'opencl.cc' || echo '$(srcdir)/'`opencl.cc enblend-opencl.obj: opencl.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-opencl.obj -MD -MP -MF $(DEPDIR)/enblend-opencl.Tpo -c -o enblend-opencl.obj `if test -f 'opencl.cc'; then $(CYGPATH_W) 'opencl.cc'; else $(CYGPATH_W) '$(srcdir)/opencl.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-opencl.Tpo $(DEPDIR)/enblend-opencl.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='opencl.cc' object='enblend-opencl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-opencl.obj `if test -f 'opencl.cc'; then $(CYGPATH_W) 'opencl.cc'; else $(CYGPATH_W) '$(srcdir)/opencl.cc'; fi` enblend-alternativepercentage.o: alternativepercentage.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-alternativepercentage.o -MD -MP -MF $(DEPDIR)/enblend-alternativepercentage.Tpo -c -o enblend-alternativepercentage.o `test -f 'alternativepercentage.cc' || echo '$(srcdir)/'`alternativepercentage.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-alternativepercentage.Tpo $(DEPDIR)/enblend-alternativepercentage.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='alternativepercentage.cc' object='enblend-alternativepercentage.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-alternativepercentage.o `test -f 'alternativepercentage.cc' || echo '$(srcdir)/'`alternativepercentage.cc enblend-alternativepercentage.obj: alternativepercentage.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-alternativepercentage.obj -MD -MP -MF $(DEPDIR)/enblend-alternativepercentage.Tpo -c -o enblend-alternativepercentage.obj `if test -f 'alternativepercentage.cc'; then $(CYGPATH_W) 'alternativepercentage.cc'; else $(CYGPATH_W) '$(srcdir)/alternativepercentage.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-alternativepercentage.Tpo $(DEPDIR)/enblend-alternativepercentage.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='alternativepercentage.cc' object='enblend-alternativepercentage.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-alternativepercentage.obj `if test -f 'alternativepercentage.cc'; then $(CYGPATH_W) 'alternativepercentage.cc'; else $(CYGPATH_W) '$(srcdir)/alternativepercentage.cc'; fi` enblend-error_message.o: error_message.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-error_message.o -MD -MP -MF $(DEPDIR)/enblend-error_message.Tpo -c -o enblend-error_message.o `test -f 'error_message.cc' || echo '$(srcdir)/'`error_message.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-error_message.Tpo $(DEPDIR)/enblend-error_message.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='error_message.cc' object='enblend-error_message.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-error_message.o `test -f 'error_message.cc' || echo '$(srcdir)/'`error_message.cc enblend-error_message.obj: error_message.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-error_message.obj -MD -MP -MF $(DEPDIR)/enblend-error_message.Tpo -c -o enblend-error_message.obj `if test -f 'error_message.cc'; then $(CYGPATH_W) 'error_message.cc'; else $(CYGPATH_W) '$(srcdir)/error_message.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-error_message.Tpo $(DEPDIR)/enblend-error_message.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='error_message.cc' object='enblend-error_message.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-error_message.obj `if test -f 'error_message.cc'; then $(CYGPATH_W) 'error_message.cc'; else $(CYGPATH_W) '$(srcdir)/error_message.cc'; fi` enblend-filenameparse.o: filenameparse.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-filenameparse.o -MD -MP -MF $(DEPDIR)/enblend-filenameparse.Tpo -c -o enblend-filenameparse.o `test -f 'filenameparse.cc' || echo '$(srcdir)/'`filenameparse.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-filenameparse.Tpo $(DEPDIR)/enblend-filenameparse.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filenameparse.cc' object='enblend-filenameparse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-filenameparse.o `test -f 'filenameparse.cc' || echo '$(srcdir)/'`filenameparse.cc enblend-filenameparse.obj: filenameparse.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-filenameparse.obj -MD -MP -MF $(DEPDIR)/enblend-filenameparse.Tpo -c -o enblend-filenameparse.obj `if test -f 'filenameparse.cc'; then $(CYGPATH_W) 'filenameparse.cc'; else $(CYGPATH_W) '$(srcdir)/filenameparse.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-filenameparse.Tpo $(DEPDIR)/enblend-filenameparse.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filenameparse.cc' object='enblend-filenameparse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-filenameparse.obj `if test -f 'filenameparse.cc'; then $(CYGPATH_W) 'filenameparse.cc'; else $(CYGPATH_W) '$(srcdir)/filenameparse.cc'; fi` enblend-filespec.o: filespec.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-filespec.o -MD -MP -MF $(DEPDIR)/enblend-filespec.Tpo -c -o enblend-filespec.o `test -f 'filespec.cc' || echo '$(srcdir)/'`filespec.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-filespec.Tpo $(DEPDIR)/enblend-filespec.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filespec.cc' object='enblend-filespec.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-filespec.o `test -f 'filespec.cc' || echo '$(srcdir)/'`filespec.cc enblend-filespec.obj: filespec.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-filespec.obj -MD -MP -MF $(DEPDIR)/enblend-filespec.Tpo -c -o enblend-filespec.obj `if test -f 'filespec.cc'; then $(CYGPATH_W) 'filespec.cc'; else $(CYGPATH_W) '$(srcdir)/filespec.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-filespec.Tpo $(DEPDIR)/enblend-filespec.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filespec.cc' object='enblend-filespec.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-filespec.obj `if test -f 'filespec.cc'; then $(CYGPATH_W) 'filespec.cc'; else $(CYGPATH_W) '$(srcdir)/filespec.cc'; fi` enblend-introspection.o: introspection.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-introspection.o -MD -MP -MF $(DEPDIR)/enblend-introspection.Tpo -c -o enblend-introspection.o `test -f 'introspection.cc' || echo '$(srcdir)/'`introspection.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-introspection.Tpo $(DEPDIR)/enblend-introspection.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='introspection.cc' object='enblend-introspection.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-introspection.o `test -f 'introspection.cc' || echo '$(srcdir)/'`introspection.cc enblend-introspection.obj: introspection.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-introspection.obj -MD -MP -MF $(DEPDIR)/enblend-introspection.Tpo -c -o enblend-introspection.obj `if test -f 'introspection.cc'; then $(CYGPATH_W) 'introspection.cc'; else $(CYGPATH_W) '$(srcdir)/introspection.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-introspection.Tpo $(DEPDIR)/enblend-introspection.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='introspection.cc' object='enblend-introspection.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-introspection.obj `if test -f 'introspection.cc'; then $(CYGPATH_W) 'introspection.cc'; else $(CYGPATH_W) '$(srcdir)/introspection.cc'; fi` enblend-mersenne.o: mersenne.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-mersenne.o -MD -MP -MF $(DEPDIR)/enblend-mersenne.Tpo -c -o enblend-mersenne.o `test -f 'mersenne.cc' || echo '$(srcdir)/'`mersenne.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-mersenne.Tpo $(DEPDIR)/enblend-mersenne.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mersenne.cc' object='enblend-mersenne.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-mersenne.o `test -f 'mersenne.cc' || echo '$(srcdir)/'`mersenne.cc enblend-mersenne.obj: mersenne.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-mersenne.obj -MD -MP -MF $(DEPDIR)/enblend-mersenne.Tpo -c -o enblend-mersenne.obj `if test -f 'mersenne.cc'; then $(CYGPATH_W) 'mersenne.cc'; else $(CYGPATH_W) '$(srcdir)/mersenne.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-mersenne.Tpo $(DEPDIR)/enblend-mersenne.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mersenne.cc' object='enblend-mersenne.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-mersenne.obj `if test -f 'mersenne.cc'; then $(CYGPATH_W) 'mersenne.cc'; else $(CYGPATH_W) '$(srcdir)/mersenne.cc'; fi` enblend-parameter.o: parameter.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-parameter.o -MD -MP -MF $(DEPDIR)/enblend-parameter.Tpo -c -o enblend-parameter.o `test -f 'parameter.cc' || echo '$(srcdir)/'`parameter.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-parameter.Tpo $(DEPDIR)/enblend-parameter.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='parameter.cc' object='enblend-parameter.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-parameter.o `test -f 'parameter.cc' || echo '$(srcdir)/'`parameter.cc enblend-parameter.obj: parameter.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-parameter.obj -MD -MP -MF $(DEPDIR)/enblend-parameter.Tpo -c -o enblend-parameter.obj `if test -f 'parameter.cc'; then $(CYGPATH_W) 'parameter.cc'; else $(CYGPATH_W) '$(srcdir)/parameter.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-parameter.Tpo $(DEPDIR)/enblend-parameter.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='parameter.cc' object='enblend-parameter.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-parameter.obj `if test -f 'parameter.cc'; then $(CYGPATH_W) 'parameter.cc'; else $(CYGPATH_W) '$(srcdir)/parameter.cc'; fi` enblend-self_test.o: self_test.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-self_test.o -MD -MP -MF $(DEPDIR)/enblend-self_test.Tpo -c -o enblend-self_test.o `test -f 'self_test.cc' || echo '$(srcdir)/'`self_test.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-self_test.Tpo $(DEPDIR)/enblend-self_test.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='self_test.cc' object='enblend-self_test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-self_test.o `test -f 'self_test.cc' || echo '$(srcdir)/'`self_test.cc enblend-self_test.obj: self_test.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-self_test.obj -MD -MP -MF $(DEPDIR)/enblend-self_test.Tpo -c -o enblend-self_test.obj `if test -f 'self_test.cc'; then $(CYGPATH_W) 'self_test.cc'; else $(CYGPATH_W) '$(srcdir)/self_test.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-self_test.Tpo $(DEPDIR)/enblend-self_test.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='self_test.cc' object='enblend-self_test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-self_test.obj `if test -f 'self_test.cc'; then $(CYGPATH_W) 'self_test.cc'; else $(CYGPATH_W) '$(srcdir)/self_test.cc'; fi` enblend-tiff_message.o: tiff_message.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-tiff_message.o -MD -MP -MF $(DEPDIR)/enblend-tiff_message.Tpo -c -o enblend-tiff_message.o `test -f 'tiff_message.cc' || echo '$(srcdir)/'`tiff_message.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-tiff_message.Tpo $(DEPDIR)/enblend-tiff_message.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tiff_message.cc' object='enblend-tiff_message.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-tiff_message.o `test -f 'tiff_message.cc' || echo '$(srcdir)/'`tiff_message.cc enblend-tiff_message.obj: tiff_message.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-tiff_message.obj -MD -MP -MF $(DEPDIR)/enblend-tiff_message.Tpo -c -o enblend-tiff_message.obj `if test -f 'tiff_message.cc'; then $(CYGPATH_W) 'tiff_message.cc'; else $(CYGPATH_W) '$(srcdir)/tiff_message.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-tiff_message.Tpo $(DEPDIR)/enblend-tiff_message.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tiff_message.cc' object='enblend-tiff_message.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-tiff_message.obj `if test -f 'tiff_message.cc'; then $(CYGPATH_W) 'tiff_message.cc'; else $(CYGPATH_W) '$(srcdir)/tiff_message.cc'; fi` enblend-timer.o: timer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-timer.o -MD -MP -MF $(DEPDIR)/enblend-timer.Tpo -c -o enblend-timer.o `test -f 'timer.cc' || echo '$(srcdir)/'`timer.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-timer.Tpo $(DEPDIR)/enblend-timer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='timer.cc' object='enblend-timer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-timer.o `test -f 'timer.cc' || echo '$(srcdir)/'`timer.cc enblend-timer.obj: timer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-timer.obj -MD -MP -MF $(DEPDIR)/enblend-timer.Tpo -c -o enblend-timer.obj `if test -f 'timer.cc'; then $(CYGPATH_W) 'timer.cc'; else $(CYGPATH_W) '$(srcdir)/timer.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-timer.Tpo $(DEPDIR)/enblend-timer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='timer.cc' object='enblend-timer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-timer.obj `if test -f 'timer.cc'; then $(CYGPATH_W) 'timer.cc'; else $(CYGPATH_W) '$(srcdir)/timer.cc'; fi` enblend-minimizer.o: minimizer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-minimizer.o -MD -MP -MF $(DEPDIR)/enblend-minimizer.Tpo -c -o enblend-minimizer.o `test -f 'minimizer.cc' || echo '$(srcdir)/'`minimizer.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-minimizer.Tpo $(DEPDIR)/enblend-minimizer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='minimizer.cc' object='enblend-minimizer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-minimizer.o `test -f 'minimizer.cc' || echo '$(srcdir)/'`minimizer.cc enblend-minimizer.obj: minimizer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -MT enblend-minimizer.obj -MD -MP -MF $(DEPDIR)/enblend-minimizer.Tpo -c -o enblend-minimizer.obj `if test -f 'minimizer.cc'; then $(CYGPATH_W) 'minimizer.cc'; else $(CYGPATH_W) '$(srcdir)/minimizer.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enblend-minimizer.Tpo $(DEPDIR)/enblend-minimizer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='minimizer.cc' object='enblend-minimizer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enblend_CXXFLAGS) $(CXXFLAGS) -c -o enblend-minimizer.obj `if test -f 'minimizer.cc'; then $(CYGPATH_W) 'minimizer.cc'; else $(CYGPATH_W) '$(srcdir)/minimizer.cc'; fi` enfuse-exposure_weight.o: exposure_weight.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-exposure_weight.o -MD -MP -MF $(DEPDIR)/enfuse-exposure_weight.Tpo -c -o enfuse-exposure_weight.o `test -f 'exposure_weight.cc' || echo '$(srcdir)/'`exposure_weight.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-exposure_weight.Tpo $(DEPDIR)/enfuse-exposure_weight.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='exposure_weight.cc' object='enfuse-exposure_weight.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-exposure_weight.o `test -f 'exposure_weight.cc' || echo '$(srcdir)/'`exposure_weight.cc enfuse-exposure_weight.obj: exposure_weight.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-exposure_weight.obj -MD -MP -MF $(DEPDIR)/enfuse-exposure_weight.Tpo -c -o enfuse-exposure_weight.obj `if test -f 'exposure_weight.cc'; then $(CYGPATH_W) 'exposure_weight.cc'; else $(CYGPATH_W) '$(srcdir)/exposure_weight.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-exposure_weight.Tpo $(DEPDIR)/enfuse-exposure_weight.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='exposure_weight.cc' object='enfuse-exposure_weight.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-exposure_weight.obj `if test -f 'exposure_weight.cc'; then $(CYGPATH_W) 'exposure_weight.cc'; else $(CYGPATH_W) '$(srcdir)/exposure_weight.cc'; fi` enfuse-enfuse.o: enfuse.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-enfuse.o -MD -MP -MF $(DEPDIR)/enfuse-enfuse.Tpo -c -o enfuse-enfuse.o `test -f 'enfuse.cc' || echo '$(srcdir)/'`enfuse.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-enfuse.Tpo $(DEPDIR)/enfuse-enfuse.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='enfuse.cc' object='enfuse-enfuse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-enfuse.o `test -f 'enfuse.cc' || echo '$(srcdir)/'`enfuse.cc enfuse-enfuse.obj: enfuse.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-enfuse.obj -MD -MP -MF $(DEPDIR)/enfuse-enfuse.Tpo -c -o enfuse-enfuse.obj `if test -f 'enfuse.cc'; then $(CYGPATH_W) 'enfuse.cc'; else $(CYGPATH_W) '$(srcdir)/enfuse.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-enfuse.Tpo $(DEPDIR)/enfuse-enfuse.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='enfuse.cc' object='enfuse-enfuse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-enfuse.obj `if test -f 'enfuse.cc'; then $(CYGPATH_W) 'enfuse.cc'; else $(CYGPATH_W) '$(srcdir)/enfuse.cc'; fi` enfuse-opencl.o: opencl.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-opencl.o -MD -MP -MF $(DEPDIR)/enfuse-opencl.Tpo -c -o enfuse-opencl.o `test -f 'opencl.cc' || echo '$(srcdir)/'`opencl.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-opencl.Tpo $(DEPDIR)/enfuse-opencl.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='opencl.cc' object='enfuse-opencl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-opencl.o `test -f 'opencl.cc' || echo '$(srcdir)/'`opencl.cc enfuse-opencl.obj: opencl.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-opencl.obj -MD -MP -MF $(DEPDIR)/enfuse-opencl.Tpo -c -o enfuse-opencl.obj `if test -f 'opencl.cc'; then $(CYGPATH_W) 'opencl.cc'; else $(CYGPATH_W) '$(srcdir)/opencl.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-opencl.Tpo $(DEPDIR)/enfuse-opencl.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='opencl.cc' object='enfuse-opencl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-opencl.obj `if test -f 'opencl.cc'; then $(CYGPATH_W) 'opencl.cc'; else $(CYGPATH_W) '$(srcdir)/opencl.cc'; fi` enfuse-opencl_exposure_weight.o: opencl_exposure_weight.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-opencl_exposure_weight.o -MD -MP -MF $(DEPDIR)/enfuse-opencl_exposure_weight.Tpo -c -o enfuse-opencl_exposure_weight.o `test -f 'opencl_exposure_weight.cc' || echo '$(srcdir)/'`opencl_exposure_weight.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-opencl_exposure_weight.Tpo $(DEPDIR)/enfuse-opencl_exposure_weight.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='opencl_exposure_weight.cc' object='enfuse-opencl_exposure_weight.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-opencl_exposure_weight.o `test -f 'opencl_exposure_weight.cc' || echo '$(srcdir)/'`opencl_exposure_weight.cc enfuse-opencl_exposure_weight.obj: opencl_exposure_weight.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-opencl_exposure_weight.obj -MD -MP -MF $(DEPDIR)/enfuse-opencl_exposure_weight.Tpo -c -o enfuse-opencl_exposure_weight.obj `if test -f 'opencl_exposure_weight.cc'; then $(CYGPATH_W) 'opencl_exposure_weight.cc'; else $(CYGPATH_W) '$(srcdir)/opencl_exposure_weight.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-opencl_exposure_weight.Tpo $(DEPDIR)/enfuse-opencl_exposure_weight.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='opencl_exposure_weight.cc' object='enfuse-opencl_exposure_weight.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-opencl_exposure_weight.obj `if test -f 'opencl_exposure_weight.cc'; then $(CYGPATH_W) 'opencl_exposure_weight.cc'; else $(CYGPATH_W) '$(srcdir)/opencl_exposure_weight.cc'; fi` enfuse-alternativepercentage.o: alternativepercentage.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-alternativepercentage.o -MD -MP -MF $(DEPDIR)/enfuse-alternativepercentage.Tpo -c -o enfuse-alternativepercentage.o `test -f 'alternativepercentage.cc' || echo '$(srcdir)/'`alternativepercentage.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-alternativepercentage.Tpo $(DEPDIR)/enfuse-alternativepercentage.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='alternativepercentage.cc' object='enfuse-alternativepercentage.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-alternativepercentage.o `test -f 'alternativepercentage.cc' || echo '$(srcdir)/'`alternativepercentage.cc enfuse-alternativepercentage.obj: alternativepercentage.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-alternativepercentage.obj -MD -MP -MF $(DEPDIR)/enfuse-alternativepercentage.Tpo -c -o enfuse-alternativepercentage.obj `if test -f 'alternativepercentage.cc'; then $(CYGPATH_W) 'alternativepercentage.cc'; else $(CYGPATH_W) '$(srcdir)/alternativepercentage.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-alternativepercentage.Tpo $(DEPDIR)/enfuse-alternativepercentage.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='alternativepercentage.cc' object='enfuse-alternativepercentage.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-alternativepercentage.obj `if test -f 'alternativepercentage.cc'; then $(CYGPATH_W) 'alternativepercentage.cc'; else $(CYGPATH_W) '$(srcdir)/alternativepercentage.cc'; fi` enfuse-error_message.o: error_message.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-error_message.o -MD -MP -MF $(DEPDIR)/enfuse-error_message.Tpo -c -o enfuse-error_message.o `test -f 'error_message.cc' || echo '$(srcdir)/'`error_message.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-error_message.Tpo $(DEPDIR)/enfuse-error_message.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='error_message.cc' object='enfuse-error_message.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-error_message.o `test -f 'error_message.cc' || echo '$(srcdir)/'`error_message.cc enfuse-error_message.obj: error_message.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-error_message.obj -MD -MP -MF $(DEPDIR)/enfuse-error_message.Tpo -c -o enfuse-error_message.obj `if test -f 'error_message.cc'; then $(CYGPATH_W) 'error_message.cc'; else $(CYGPATH_W) '$(srcdir)/error_message.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-error_message.Tpo $(DEPDIR)/enfuse-error_message.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='error_message.cc' object='enfuse-error_message.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-error_message.obj `if test -f 'error_message.cc'; then $(CYGPATH_W) 'error_message.cc'; else $(CYGPATH_W) '$(srcdir)/error_message.cc'; fi` enfuse-filenameparse.o: filenameparse.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-filenameparse.o -MD -MP -MF $(DEPDIR)/enfuse-filenameparse.Tpo -c -o enfuse-filenameparse.o `test -f 'filenameparse.cc' || echo '$(srcdir)/'`filenameparse.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-filenameparse.Tpo $(DEPDIR)/enfuse-filenameparse.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filenameparse.cc' object='enfuse-filenameparse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-filenameparse.o `test -f 'filenameparse.cc' || echo '$(srcdir)/'`filenameparse.cc enfuse-filenameparse.obj: filenameparse.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-filenameparse.obj -MD -MP -MF $(DEPDIR)/enfuse-filenameparse.Tpo -c -o enfuse-filenameparse.obj `if test -f 'filenameparse.cc'; then $(CYGPATH_W) 'filenameparse.cc'; else $(CYGPATH_W) '$(srcdir)/filenameparse.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-filenameparse.Tpo $(DEPDIR)/enfuse-filenameparse.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filenameparse.cc' object='enfuse-filenameparse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-filenameparse.obj `if test -f 'filenameparse.cc'; then $(CYGPATH_W) 'filenameparse.cc'; else $(CYGPATH_W) '$(srcdir)/filenameparse.cc'; fi` enfuse-filespec.o: filespec.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-filespec.o -MD -MP -MF $(DEPDIR)/enfuse-filespec.Tpo -c -o enfuse-filespec.o `test -f 'filespec.cc' || echo '$(srcdir)/'`filespec.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-filespec.Tpo $(DEPDIR)/enfuse-filespec.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filespec.cc' object='enfuse-filespec.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-filespec.o `test -f 'filespec.cc' || echo '$(srcdir)/'`filespec.cc enfuse-filespec.obj: filespec.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-filespec.obj -MD -MP -MF $(DEPDIR)/enfuse-filespec.Tpo -c -o enfuse-filespec.obj `if test -f 'filespec.cc'; then $(CYGPATH_W) 'filespec.cc'; else $(CYGPATH_W) '$(srcdir)/filespec.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-filespec.Tpo $(DEPDIR)/enfuse-filespec.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='filespec.cc' object='enfuse-filespec.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-filespec.obj `if test -f 'filespec.cc'; then $(CYGPATH_W) 'filespec.cc'; else $(CYGPATH_W) '$(srcdir)/filespec.cc'; fi` enfuse-introspection.o: introspection.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-introspection.o -MD -MP -MF $(DEPDIR)/enfuse-introspection.Tpo -c -o enfuse-introspection.o `test -f 'introspection.cc' || echo '$(srcdir)/'`introspection.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-introspection.Tpo $(DEPDIR)/enfuse-introspection.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='introspection.cc' object='enfuse-introspection.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-introspection.o `test -f 'introspection.cc' || echo '$(srcdir)/'`introspection.cc enfuse-introspection.obj: introspection.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-introspection.obj -MD -MP -MF $(DEPDIR)/enfuse-introspection.Tpo -c -o enfuse-introspection.obj `if test -f 'introspection.cc'; then $(CYGPATH_W) 'introspection.cc'; else $(CYGPATH_W) '$(srcdir)/introspection.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-introspection.Tpo $(DEPDIR)/enfuse-introspection.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='introspection.cc' object='enfuse-introspection.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-introspection.obj `if test -f 'introspection.cc'; then $(CYGPATH_W) 'introspection.cc'; else $(CYGPATH_W) '$(srcdir)/introspection.cc'; fi` enfuse-mersenne.o: mersenne.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-mersenne.o -MD -MP -MF $(DEPDIR)/enfuse-mersenne.Tpo -c -o enfuse-mersenne.o `test -f 'mersenne.cc' || echo '$(srcdir)/'`mersenne.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-mersenne.Tpo $(DEPDIR)/enfuse-mersenne.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mersenne.cc' object='enfuse-mersenne.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-mersenne.o `test -f 'mersenne.cc' || echo '$(srcdir)/'`mersenne.cc enfuse-mersenne.obj: mersenne.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-mersenne.obj -MD -MP -MF $(DEPDIR)/enfuse-mersenne.Tpo -c -o enfuse-mersenne.obj `if test -f 'mersenne.cc'; then $(CYGPATH_W) 'mersenne.cc'; else $(CYGPATH_W) '$(srcdir)/mersenne.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-mersenne.Tpo $(DEPDIR)/enfuse-mersenne.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mersenne.cc' object='enfuse-mersenne.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-mersenne.obj `if test -f 'mersenne.cc'; then $(CYGPATH_W) 'mersenne.cc'; else $(CYGPATH_W) '$(srcdir)/mersenne.cc'; fi` enfuse-parameter.o: parameter.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-parameter.o -MD -MP -MF $(DEPDIR)/enfuse-parameter.Tpo -c -o enfuse-parameter.o `test -f 'parameter.cc' || echo '$(srcdir)/'`parameter.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-parameter.Tpo $(DEPDIR)/enfuse-parameter.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='parameter.cc' object='enfuse-parameter.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-parameter.o `test -f 'parameter.cc' || echo '$(srcdir)/'`parameter.cc enfuse-parameter.obj: parameter.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-parameter.obj -MD -MP -MF $(DEPDIR)/enfuse-parameter.Tpo -c -o enfuse-parameter.obj `if test -f 'parameter.cc'; then $(CYGPATH_W) 'parameter.cc'; else $(CYGPATH_W) '$(srcdir)/parameter.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-parameter.Tpo $(DEPDIR)/enfuse-parameter.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='parameter.cc' object='enfuse-parameter.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-parameter.obj `if test -f 'parameter.cc'; then $(CYGPATH_W) 'parameter.cc'; else $(CYGPATH_W) '$(srcdir)/parameter.cc'; fi` enfuse-self_test.o: self_test.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-self_test.o -MD -MP -MF $(DEPDIR)/enfuse-self_test.Tpo -c -o enfuse-self_test.o `test -f 'self_test.cc' || echo '$(srcdir)/'`self_test.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-self_test.Tpo $(DEPDIR)/enfuse-self_test.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='self_test.cc' object='enfuse-self_test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-self_test.o `test -f 'self_test.cc' || echo '$(srcdir)/'`self_test.cc enfuse-self_test.obj: self_test.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-self_test.obj -MD -MP -MF $(DEPDIR)/enfuse-self_test.Tpo -c -o enfuse-self_test.obj `if test -f 'self_test.cc'; then $(CYGPATH_W) 'self_test.cc'; else $(CYGPATH_W) '$(srcdir)/self_test.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-self_test.Tpo $(DEPDIR)/enfuse-self_test.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='self_test.cc' object='enfuse-self_test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-self_test.obj `if test -f 'self_test.cc'; then $(CYGPATH_W) 'self_test.cc'; else $(CYGPATH_W) '$(srcdir)/self_test.cc'; fi` enfuse-tiff_message.o: tiff_message.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-tiff_message.o -MD -MP -MF $(DEPDIR)/enfuse-tiff_message.Tpo -c -o enfuse-tiff_message.o `test -f 'tiff_message.cc' || echo '$(srcdir)/'`tiff_message.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-tiff_message.Tpo $(DEPDIR)/enfuse-tiff_message.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tiff_message.cc' object='enfuse-tiff_message.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-tiff_message.o `test -f 'tiff_message.cc' || echo '$(srcdir)/'`tiff_message.cc enfuse-tiff_message.obj: tiff_message.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-tiff_message.obj -MD -MP -MF $(DEPDIR)/enfuse-tiff_message.Tpo -c -o enfuse-tiff_message.obj `if test -f 'tiff_message.cc'; then $(CYGPATH_W) 'tiff_message.cc'; else $(CYGPATH_W) '$(srcdir)/tiff_message.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-tiff_message.Tpo $(DEPDIR)/enfuse-tiff_message.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tiff_message.cc' object='enfuse-tiff_message.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-tiff_message.obj `if test -f 'tiff_message.cc'; then $(CYGPATH_W) 'tiff_message.cc'; else $(CYGPATH_W) '$(srcdir)/tiff_message.cc'; fi` enfuse-timer.o: timer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-timer.o -MD -MP -MF $(DEPDIR)/enfuse-timer.Tpo -c -o enfuse-timer.o `test -f 'timer.cc' || echo '$(srcdir)/'`timer.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-timer.Tpo $(DEPDIR)/enfuse-timer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='timer.cc' object='enfuse-timer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-timer.o `test -f 'timer.cc' || echo '$(srcdir)/'`timer.cc enfuse-timer.obj: timer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-timer.obj -MD -MP -MF $(DEPDIR)/enfuse-timer.Tpo -c -o enfuse-timer.obj `if test -f 'timer.cc'; then $(CYGPATH_W) 'timer.cc'; else $(CYGPATH_W) '$(srcdir)/timer.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-timer.Tpo $(DEPDIR)/enfuse-timer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='timer.cc' object='enfuse-timer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-timer.obj `if test -f 'timer.cc'; then $(CYGPATH_W) 'timer.cc'; else $(CYGPATH_W) '$(srcdir)/timer.cc'; fi` enfuse-minimizer.o: minimizer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-minimizer.o -MD -MP -MF $(DEPDIR)/enfuse-minimizer.Tpo -c -o enfuse-minimizer.o `test -f 'minimizer.cc' || echo '$(srcdir)/'`minimizer.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-minimizer.Tpo $(DEPDIR)/enfuse-minimizer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='minimizer.cc' object='enfuse-minimizer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-minimizer.o `test -f 'minimizer.cc' || echo '$(srcdir)/'`minimizer.cc enfuse-minimizer.obj: minimizer.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -MT enfuse-minimizer.obj -MD -MP -MF $(DEPDIR)/enfuse-minimizer.Tpo -c -o enfuse-minimizer.obj `if test -f 'minimizer.cc'; then $(CYGPATH_W) 'minimizer.cc'; else $(CYGPATH_W) '$(srcdir)/minimizer.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/enfuse-minimizer.Tpo $(DEPDIR)/enfuse-minimizer.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='minimizer.cc' object='enfuse-minimizer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(enfuse_CXXFLAGS) $(CXXFLAGS) -c -o enfuse-minimizer.obj `if test -f 'minimizer.cc'; then $(CYGPATH_W) 'minimizer.cc'; else $(CYGPATH_W) '$(srcdir)/minimizer.cc'; fi` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(PROGRAMS) $(MANS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-man install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-man1 install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: $(am__recursive_targets) all check install install-am \ install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-binPROGRAMS clean-generic cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man1 install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-man uninstall-man1 %.icl: %.cl $(AM_V_GEN)$(srcdir)/embrace --format=c++ --label=$(basename $(notdir $<))_source_code $< > $@ calculate_state_probabilities.icl: calculate_state_probabilities.cl distance_transform_fh.icl: distance_transform_fh.cl signature.h: $(srcdir)/gen_sig $(srcdir)/DefaultSig.pm $(srcdir)/Sig.pm @ $(PERL) -I$(srcdir) $< --extra=$(VERSION) > $@ #dist_man_MANS = enblend.1 enfuse.1 .PHONY: man man: enblend.1 enfuse.1 enblend.1: enblend $(AM_V_GEN)$(HELP2MAN) --no-info --output=$@ ./enblend enfuse.1: enfuse $(AM_V_GEN)$(HELP2MAN) --no-info --output=$@ ./enfuse # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: enblend-enfuse-4.2/src/opencl.cc0000644000175000017500000015134712676175540013600 00000000000000/* * Copyright (C) 2013-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include // va_list #include // std::ifstream #include #include #include // std::istream_iterator #include #include // std::accumulate #include "opencl.h" namespace ocl { StowFormatFlags::StowFormatFlags() { push(); } StowFormatFlags::~StowFormatFlags() { pop(); } void StowFormatFlags::push() { cin_flags_.push(std::cin.flags()); cout_flags_.push(std::cout.flags()); cerr_flags_.push(std::cerr.flags()); } void StowFormatFlags::pop() { std::cin.flags(cin_flags_.top()); cin_flags_.pop(); std::cout.flags(cout_flags_.top()); cout_flags_.pop(); std::cerr.flags(cerr_flags_.top()); cerr_flags_.pop(); } //////////////////////////////////////////////////////////////////////// std::vector split_string(const std::string& a_string, char a_delimiter, bool keep_empty_tokens) { std::stringstream s(a_string); std::vector tokens; std::string t; while (std::getline(s, t, a_delimiter)) { if (keep_empty_tokens || !t.empty()) { tokens.push_back(t); } } return tokens; } template static std::string concatenate(const std::string& a_separator, iterator a_begin, iterator an_end) { if (a_begin == an_end) { return std::string(); } else { std::string result(*a_begin); while (++a_begin != an_end) { result.append(a_separator).append(*a_begin); } return result; } } #if defined(OPENCL) #define UNINITIALIZED_OPENCL_ERROR_CODE -7927 runtime_error::runtime_error(const std::string& a_message) : std::runtime_error(a_message), opencl_error_(UNINITIALIZED_OPENCL_ERROR_CODE) {} runtime_error::runtime_error(const cl::Error& an_opencl_error, const std::string& an_additional_message) : std::runtime_error(string_of_error_code(an_opencl_error.err())), opencl_error_(an_opencl_error), additional_message_(an_additional_message) {} const cl::Error& runtime_error::error() const { return opencl_error_; } const std::string& runtime_error::additional_message() const { return additional_message_; } std::string string_of_error_code(cl_int an_error_code) { switch (an_error_code) { case CL_SUCCESS: return "success"; // not an error case CL_DEVICE_NOT_FOUND: return "device not found"; case CL_DEVICE_NOT_AVAILABLE: return "device not available"; case CL_COMPILER_NOT_AVAILABLE: return "compiler not available"; case CL_MEM_OBJECT_ALLOCATION_FAILURE: return "memory object allocation failure"; case CL_OUT_OF_RESOURCES: return "out of resources"; case CL_OUT_OF_HOST_MEMORY: return "out of host memory"; case CL_PROFILING_INFO_NOT_AVAILABLE: return "profiling information not available"; case CL_MEM_COPY_OVERLAP: return "memory copy overlap"; case CL_IMAGE_FORMAT_MISMATCH: return "image format mismatch"; case CL_IMAGE_FORMAT_NOT_SUPPORTED: return "image format not supported"; case CL_BUILD_PROGRAM_FAILURE: return "build program failure"; case CL_MAP_FAILURE: return "map failure"; case CL_MISALIGNED_SUB_BUFFER_OFFSET: return "misaligned sub buffer offset"; case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST: return "exec status error for events in wait list"; case CL_INVALID_VALUE: return "invalid value"; case CL_INVALID_DEVICE_TYPE: return "invalid device type"; case CL_INVALID_PLATFORM: return "invalid platform"; case CL_INVALID_DEVICE: return "invalid device"; case CL_INVALID_CONTEXT: return "invalid context"; case CL_INVALID_QUEUE_PROPERTIES: return "invalid queue properties"; case CL_INVALID_COMMAND_QUEUE: return "invalid command queue"; case CL_INVALID_HOST_PTR: return "invalid host pointer"; case CL_INVALID_MEM_OBJECT: return "invalid memory object"; case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: return "invalid image format descriptor"; case CL_INVALID_IMAGE_SIZE: return "invalid image size"; case CL_INVALID_SAMPLER: return "invalid sampler"; case CL_INVALID_BINARY: return "invalid binary"; case CL_INVALID_BUILD_OPTIONS: return "invalid build options"; case CL_INVALID_PROGRAM: return "invalid program"; case CL_INVALID_PROGRAM_EXECUTABLE: return "invalid program executable"; case CL_INVALID_KERNEL_NAME: return "invalid kernel name"; case CL_INVALID_KERNEL_DEFINITION: return "invalid kernel definition"; case CL_INVALID_KERNEL: return "invalid kernel"; case CL_INVALID_ARG_INDEX: return "invalid argument index"; case CL_INVALID_ARG_VALUE: return "invalid argument value"; case CL_INVALID_ARG_SIZE: return "invalid argument size"; case CL_INVALID_KERNEL_ARGS: return "invalid kernel arguments"; case CL_INVALID_WORK_DIMENSION: return "invalid work dimension"; case CL_INVALID_WORK_GROUP_SIZE: return "invalid work group size"; case CL_INVALID_WORK_ITEM_SIZE: return "invalid work item size"; case CL_INVALID_GLOBAL_OFFSET: return "invalid global offset"; case CL_INVALID_EVENT_WAIT_LIST: return "invalid event wait list"; case CL_INVALID_EVENT: return "invalid event"; case CL_INVALID_OPERATION: return "invalid operation"; case CL_INVALID_GL_OBJECT: return "invalid GL object"; case CL_INVALID_BUFFER_SIZE: return "invalid buffer size"; case CL_INVALID_MIP_LEVEL: return "invalid MIP level"; case CL_INVALID_GLOBAL_WORK_SIZE: return "invalid global work size"; case CL_INVALID_PROPERTY: return "invalid property"; case UNINITIALIZED_OPENCL_ERROR_CODE: return "no further pending OpenCL errors"; default: std::ostringstream error_code; error_code << "unknown error code " << an_error_code; return error_code.str(); } } //////////////////////////////////////////////////////////////////////// ShowProfileData::ShowProfileData() : device_(nullptr) {} ShowProfileData::~ShowProfileData() {} void ShowProfileData::set_device(const cl::Device* a_device) { device_ = a_device; } void ShowProfileData::add_result(const std::string& a_label, double a_latency) { result_t::iterator existing_label = std::find_if(results_.begin(), results_.end(), [&] (const Measurement& measurement) { return measurement.label == a_label; }); if (existing_label == results_.end()) { results_.push_back(Measurement(a_label, a_latency)); } else { existing_label->latency += a_latency; existing_label->multi = true; } } void ShowProfileData::add_event_latency(const std::string& a_label, cl::Event& an_event) { add_result(a_label, event_latency(an_event)); } template void ShowProfileData::add_event_latencies(const std::string& a_label, input_iterator a_first, input_iterator a_last) { std::for_each(a_first, a_last, [&] (cl::Event& event) { ShowProfileData::add_event_latency(a_label, event); }); } typedef std::vector event_list; typedef event_list::iterator event_list_iterator; template void ShowProfileData::add_event_latencies (const std::string&, event_list_iterator, event_list_iterator); void ShowProfileData::clear_results() { results_.clear(); } double ShowProfileData::total_latency() const { return std::accumulate(results_.begin(), results_.end(), double(), [] (double partial_sum, const Measurement& measurement) { return partial_sum + measurement.latency; }); } static double base_unit_factor(ShowProfileData::base_unit_t a_base_unit) { switch(a_base_unit) { case ShowProfileData::NANO_SECONDS: return 1e-9; case ShowProfileData::MICRO_SECONDS: return 1e-6; case ShowProfileData::MILLI_SECONDS: return 1e-3; default: return 1.0; } } static std::string base_unit_abbreviation(ShowProfileData::base_unit_t a_base_unit) { switch(a_base_unit) { case ShowProfileData::NANO_SECONDS: return "ns"; case ShowProfileData::MICRO_SECONDS: return "µs"; case ShowProfileData::MILLI_SECONDS: return "ms"; default: return "s"; } } double ShowProfileData::retrieve_result(const std::string& a_label, base_unit_t a_base_unit) const { result_t::const_iterator measurement = std::find_if(results_.begin(), results_.end(), [&] (const Measurement& measurement) { return measurement.label == a_label; }); if (measurement == results_.end()) { throw std::runtime_error("measurement label not found"); } else { return measurement->latency / base_unit_factor(a_base_unit); } } void ShowProfileData::show_results(std::ostream& an_output_stream, const std::string& a_prefix, base_unit_t a_base_unit) const { const double total = total_latency(); result_t results_and_total(results_); results_and_total.push_back(Measurement("TOTAL", total)); StowFormatFlags _; an_output_stream << a_prefix << "timing: event m latency rel.lat\n" << a_prefix << "timing: ---------------- - ----------- -------\n"; for (auto& r : results_and_total) { an_output_stream << a_prefix << "timing: " << std::setw(16) << r.label << (r.multi ? " + " : " ") << std::fixed << std::setw(8) << std::setprecision(1) << r.latency / base_unit_factor(a_base_unit) << " " << base_unit_abbreviation(a_base_unit) << " " << std::setw(6) << std::setprecision(1) << 100.0 * r.latency / total << "%\n"; } an_output_stream << a_prefix << "timing: Plus signs (\"+\") in the m(ulti)-column indicate\n" << a_prefix << "timing: accumulated results.\n"; if (device_) { // Timer resolution is given in nano seconds, therefore we // convert to seconds before applying base_unit_factor(). const double resolution = 1e-9 * device_->getInfo(); an_output_stream << a_prefix << "timing: Device profiling timer resolution " << std::setprecision(3) << resolution / base_unit_factor(a_base_unit) << " " << base_unit_abbreviation(a_base_unit) << ".\n"; } } //////////////////////////////////////////////////////////////////////// static void print_platform_info(platform_list_t::const_iterator a_platform, unsigned a_platform_index) { std::string info; a_platform->getInfo(CL_PLATFORM_VENDOR, &info); std::cout << " - Platform #" << a_platform_index << ": " << info; a_platform->getInfo(CL_PLATFORM_NAME, &info); std::cout << ", " << info; a_platform->getInfo(CL_PLATFORM_VERSION, &info); std::cout << ", " << info << "\n"; } static void print_device_info(device_list_t::const_iterator a_device, unsigned a_device_index) { std::cout << " * Device #" << a_device_index << ": max. " << a_device->getInfo() << " work-items\n" << " " << a_device->getInfo() / 1024UL << " KB global memory "; switch (a_device->getInfo()) { case CL_NONE: std::cout << "without associated cache"; break; case CL_READ_ONLY_CACHE: std::cout << "with " << a_device->getInfo() / 1024UL << " KB read cache"; break; case CL_READ_WRITE_CACHE: std::cout << "with " << a_device->getInfo() / 1024UL << " KB read/write cache"; } std::cout << "\n" << " " << a_device->getInfo() / 1024UL << " KB " << (a_device->getInfo() == CL_LOCAL ? "dedicated " : "") << "local memory\n" << " " << a_device->getInfo() / 1024UL << " KB maximum constant memory\n"; std::vector device_extensions; query_device_extensions(*a_device, std::back_inserter(device_extensions)); std::sort(device_extensions.begin(), device_extensions.end()); std::cout << " Extensions:\n"; for (auto x : device_extensions) { std::cout << " " << x << "\n"; } } struct no_platform : runtime_error { no_platform() : runtime_error("no OpenCL platform found") {} explicit no_platform(const std::string& a_message) : runtime_error(a_message) {} }; struct no_device : runtime_error { no_device() : runtime_error("no OpenCL device found") {} explicit no_device(const std::string& a_message) : runtime_error(a_message) {} }; #define OPENCL_PATH "ENBLEND_OPENCL_PATH" //< opencl-path ENBLEND_OPENCL_PATH std::vector construct_search_path() { // We _always_ search a_filename along of some explicit, given // path, never implicitly through CWD or the direcory of the // binary. std::vector paths; if (getenv(OPENCL_PATH)) { paths.push_back(getenv(OPENCL_PATH)); } #ifdef _WIN32 // on Windows fixed paths would be too restricting // construct the search path relative to the binary path char buffer[MAX_PATH]; //always use MAX_PATH for filepaths GetModuleFileName(NULL, buffer, sizeof(buffer)); std::string working_path(buffer); //remove filename std::string::size_type pos = working_path.rfind("\\"); if (pos != std::string::npos) { working_path.erase(pos); //remove last dir: should be bin pos = working_path.rfind("\\"); if (pos != std::string::npos) { working_path.erase(pos); working_path.append("\\share\\enblend\\kernels"); paths.push_back(working_path); } } #else paths.push_back(DEFAULT_OPENCL_PATH); #endif return paths; } void print_opencl_information(bool all_devices) { platform_list_t platforms; cl::Platform::get(&platforms); if (platforms.empty()) { std::cout << " - no platform found\n"; } else { unsigned platform_index = 1U; // We start enumerating at 1 for user convenience. for (auto p = platforms.begin(); p != platforms.end(); ++p, ++platform_index) { print_platform_info(p, platform_index); device_list_t devices; try { p->getDevices(all_devices ? CL_DEVICE_TYPE_ALL : CL_DEVICE_TYPE_GPU, &devices); } catch (cl::Error& an_error) { // CL_DEVICE_NOT_FOUND is a possible error that // does not hurt as the variable `devices' will be // empty() then, which will be checked below. if (an_error.err() != CL_DEVICE_NOT_FOUND) { throw an_error; } } if (devices.empty()) { std::cout << " * no " << (all_devices ? "" : "GPU ") << "devices found on this platform\n"; } else { unsigned device_index = 1U; // Again, we start enumerating at 1 for user convenience. for (auto d = devices.begin(); d != devices.end(); ++d, ++device_index) { print_device_info(d, device_index); } } } } #if defined PREFER_SEPARATE_OPENCL_SOURCE || defined ENFUSE_SOURCE { const std::vector paths(construct_search_path()); std::cout << " Search path (expanding " OPENCL_PATH " and appending built-in path)\n "; if (paths.empty()) { std::cout << ""; } else { #ifdef _WIN32 std::cout << concatenate(";", paths.begin(), paths.end()); #else std::cout << concatenate(":", paths.begin(), paths.end()); #endif } std::cout << "\n"; } #endif // PREFER_SEPARATE_OPENCL_SOURCE || ENFUSE_SOURCE } void print_gpu_preference(size_t a_preferred_platform_id, size_t a_preferred_device_id) { try { size_t platform_id = a_preferred_platform_id; cl::Platform platform; device_list_t some_devices; platform = find_platform(platform_id); prefer_device(platform, a_preferred_platform_id, a_preferred_device_id, some_devices); std::cout << "Currently preferred GPU is device #" << a_preferred_device_id << " on platform #" << platform_id << (a_preferred_platform_id == 0U ? " (auto-detected)" : "") << ".\n"; } catch (no_platform&) { std::cout << "No OpenCL platforms found.\n"; } catch (no_device&) { std::cout << "No OpenCL (GPU) devices found on any platform.\n"; } catch (runtime_error& an_error) { std::cout << "Platform number #" << a_preferred_platform_id << (a_preferred_platform_id == 0U ? " (auto-detected)" : "") << "/device number #" << a_preferred_device_id << " combination is invalid for this system.\n" << an_error.what() << "\n"; } } cl::Platform find_platform(size_t& a_preferred_platform_id) { std::ostringstream message; platform_list_t platforms; try { cl::Platform::get(&platforms); } catch (cl::Error& an_error) { message << "query for OpenCL platforms failed: " << ocl::string_of_error_code(an_error.err()); throw ocl::runtime_error(message.str()); } if (platforms.empty()) { throw no_platform(); } else { if (a_preferred_platform_id == 0U) { ocl::platform_list_t::const_iterator p = std::find_if(platforms.begin(), platforms.end(), [](const cl::Platform& a_platform) { ocl::device_list_t devices; try {a_platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);} catch (cl::Error&) {return false;} return devices.size() >= 1U; }); if (p == platforms.end()) { throw no_device(); } else { a_preferred_platform_id = p - platforms.begin() + 1U; return *p; } } else if (a_preferred_platform_id <= platforms.size()) { return platforms[a_preferred_platform_id - 1U]; } else { message << "OpenCL platform #" << a_preferred_platform_id << " is not available; largest OpenCL platform number is " << platforms.size(); throw ocl::runtime_error(message.str()); } } } void prefer_device(const cl::Platform& a_platform, size_t a_preferred_platform_id, size_t a_preferred_device_id, device_list_t& some_devices) { std::ostringstream message; try { a_platform.getDevices(CL_DEVICE_TYPE_GPU, &some_devices); } catch (cl::Error& an_error) { message << "query for OpenCL GPU devices on platform #" << a_preferred_platform_id + 1U << " failed: " << ocl::string_of_error_code(an_error.err()); throw ocl::runtime_error(message.str()); } if (some_devices.empty()) { message << "no OpenCL GPU device found on platform #" << a_preferred_platform_id; throw no_device(message.str()); } else { if (a_preferred_device_id <= some_devices.size()) { // move the preferred device in front some_devices.insert(some_devices.begin(), some_devices[a_preferred_device_id - 1U]); some_devices.erase(some_devices.begin() + a_preferred_device_id); } else { message << "OpenCL device #" << a_preferred_device_id << " is not available on platform #" << a_preferred_platform_id + 1U << ", largest device number there is " << some_devices.size(); throw ocl::runtime_error(message.str()); } } } static void run_self_tests(cl::Context* a_context) { std::ostringstream message; // a_context must be usable. std::vector context_properties; try { a_context->getInfo(CL_CONTEXT_PROPERTIES, &context_properties); } catch (cl::Error& an_error) { message << "self test failed: cannot query properties of context: " << ocl::string_of_error_code(an_error.err()); throw ocl::runtime_error(message.str()); } // We need at least one device. std::vector devices; try { a_context->getInfo(CL_CONTEXT_DEVICES, &devices); } catch (cl::Error& an_error) { message << "self test failed: cannot query devices in context: " << ocl::string_of_error_code(an_error.err()); throw ocl::runtime_error(message.str()); } if (devices.empty()) { throw no_device(); } } cl::Context* create_context(const cl::Platform& a_platform, const device_list_t& some_devices) { cl_context_properties context_properties[] = { CL_CONTEXT_PLATFORM, reinterpret_cast(a_platform()), cl_context_properties() }; cl::Context* context = nullptr; try { context = new cl::Context(some_devices, context_properties, nullptr, nullptr); } catch (cl::Error& an_error) { std::ostringstream message; message << "failed to create OpenCL context: " << ocl::string_of_error_code(an_error.err()); throw ocl::runtime_error(message.str()); } run_self_tests(context); return context; } // Answer the iterator pointing to a property in a context // property list defined by a_begin and an_end that is associated // with a_key or an_end, if not found. template inline static iterator find_property(const iterator a_begin, const iterator an_end, const typename iterator::value_type& a_key) { iterator x(std::find(a_begin, an_end, a_key)); return x == an_end ? an_end : ++x; } static std::string derive_vendor_name_from_context(const cl::Context* a_context) { typedef std::vector property_list; typedef property_list::const_iterator iterator; const property_list properties(a_context->getInfo()); const iterator platform_property(find_property(properties.begin(), properties.end(), CL_CONTEXT_PLATFORM)); if (platform_property != properties.end()) { cl::Platform platform(reinterpret_cast(*platform_property)); return platform.getInfo(); } else { return std::string(); } } vendor::id_t derive_vendor_id_from_context(const cl::Context* a_context) { const std::string name(derive_vendor_name_from_context(a_context)); auto is_prefix_of_name = [&](const char* a_prefix) {return strncasecmp(a_prefix, name.c_str(), strlen(a_prefix)) == 0;}; if (is_prefix_of_name("Advanced Micro Devices")) { return vendor::amd; } else if (is_prefix_of_name("Apple")) { return vendor::apple; } else if (is_prefix_of_name("NVIDIA")) { return vendor::nvidia; } else { std::cout << "+ ocl::derive_vendor_id_from_context: unknown vendor name <" << name << ">\n" << "+ ocl::derive_vendor_id_from_context: please add vendor name to file \"opencl.cc\"!\n"; return vendor::unknown; } } //////////////////////////////////////////////////////////////////////////// template inline static t* data(std::vector& a_vector) { return a_vector.empty() ? nullptr : &a_vector[0]; } template inline static const t* data(const std::vector& a_vector) { return a_vector.empty() ? nullptr : &a_vector[0]; } template inline static typename std::underlying_type::type as_int(Enumeration a_value) { return static_cast::type>(a_value); } static std::string expand_twiddle(const std::string& a_path) { std::string result(a_path); #ifndef _WIN32 // on Windows this replacement would break with short filenames with always contains a tilde const char* home = getenv("HOME"); if (home) { while (true) { const std::string::size_type twiddle(result.find('~')); if (twiddle == std::string::npos) { break; } result.replace(twiddle, 1U, home); } } #endif return result; } static std::string find_file_in_path(const std::string& a_source_filename, const std::string& a_path, char a_directory_separator = '/', char a_path_separator = ':') { const std::vector directories = split_string(a_path, a_path_separator); auto directory = std::find_if(directories.begin(), directories.end(), [&a_directory_separator, &a_source_filename](const std::string& a_directory) { const std::string filename(expand_twiddle(a_directory) + a_directory_separator + a_source_filename); std::ifstream file(filename.c_str()); return file.is_open(); }); if (directory == directories.end()) { return std::string(); } else { return *directory + a_directory_separator + a_source_filename; } } static std::string find_file(const std::string& a_filename) { const char a_directory_separator = '/'; #ifdef _WIN32 const char a_path_separator = ';'; bool abs_path = false; if (a_filename.size() >= 3U) { abs_path = ((a_filename[1U] == ':' && a_filename[2U] == '\\') || (a_filename[1U] == ':' && a_filename[2U] == '/') || (a_filename[0U] == '\\' && a_filename[1U] == '\\')); }; #else const char a_path_separator = ':'; bool abs_path = a_filename.size() >= 1U && a_filename[0U] == a_directory_separator; #endif if (abs_path) { return a_filename; // honor absolute path } else { const std::vector paths(construct_search_path()); for (auto p : paths) { const std::string f = find_file_in_path(a_filename, p, a_directory_separator, a_path_separator); if (!f.empty()) { return f; } } return std::string(); } } std::string consult_file(const std::string& a_filename) { typedef std::istreambuf_iterator file_iterator; std::ifstream file(find_file(a_filename).c_str()); if (!file) { std::ostringstream message; message << "file not found: missing \"" << a_filename << "\""; throw std::runtime_error(message.str()); } else { std::string result; result.assign(file_iterator(file), (file_iterator())); file.close(); return result; } } static std::string string_of_variable_arguments(const char *a_format_string, va_list a_variable_argument_list) { enum struct Limits : size_t {initial_size = 4096, maximum_size = 256 * 4096}; size_t buffer_size(as_int(Limits::initial_size)); char* buffer; while (true) { buffer = new char[buffer_size]; size_t actual_size = vsnprintf(buffer, buffer_size, a_format_string, a_variable_argument_list); if (actual_size < buffer_size) { break; } delete [] buffer; buffer_size *= 2U; if (buffer_size > as_int(Limits::maximum_size)) { throw ocl::runtime_error("excessively large vnsprintf buffer"); } } std::string result(buffer); delete [] buffer; return result; } double event_latency(cl::Event& an_event) { an_event.wait(); const double start_time = static_cast(an_event.getProfilingInfo()); const double end_time = static_cast(an_event.getProfilingInfo()); return 1e-9 * (end_time - start_time); } void check_opencl_event(cl::Event& an_event, const char* a_filename, int a_linenumber) { try { const cl_int return_code = an_event.wait(); if (return_code != CL_SUCCESS) { std::cerr << "\n*** CHECK_OPENCL_EVENT failed at " << a_filename << ":" << a_linenumber << " with code " << return_code << std::endl; exit(1); } } catch (cl::Error& an_error) { std::cerr << "\n*** CHECK_OPENCL_EVENT raised `" << an_error.what() << "', code `" << string_of_error_code(an_error.err()) << "' at " << a_filename << ":" << a_linenumber << std::endl; exit(1); } catch (...) { std::cerr << "\n*** CHECK_OPENCL_EVENT threw at " << a_filename << ":" << a_linenumber << std::endl; exit(1); } } //////////////////////////////////////////////////////////////////////////// std::pair SourcePolicy::source() { return std::make_pair(text().c_str(), text().length()); } std::pair BinaryPolicy::binary() { return std::make_pair(static_cast(data(code())), code().size()); } SourceStringPolicy::SourceStringPolicy(const std::string& a_source_text) : text_(a_source_text) {} const std::string& SourceStringPolicy::text() { assert(!text_.empty()); return text_; } SourceFilePolicy::SourceFilePolicy(const std::string& a_source_filename) : filename_(a_source_filename) {} const std::string& SourceFilePolicy::text() { if (text_.empty()) { consult(); assert(!text_.empty()); } return text_; } void SourceFilePolicy::consult() { text_ = consult_file(filename_); } BinaryCodePolicy::BinaryCodePolicy(const BinaryPolicy::code_t& a_binary_code) : code_(a_binary_code) {} BinaryFilePolicy::BinaryFilePolicy(const std::string& a_binary_filename) : filename_(a_binary_filename) {} BinaryPolicy::code_t BinaryFilePolicy::code() { if (code_.size() == 0U) { consult(); assert(code_.size() != 0U); } return code_; } void BinaryFilePolicy::consult() { typedef std::istream_iterator file_iterator; std::ifstream file(find_file(filename_).c_str()); if (!file) { std::ostringstream message; message << "OpenCL binary file not found; missing \"" << filename_ << "\""; throw ocl::runtime_error(message.str()); } file_iterator iter(file); std::copy(iter, file_iterator(), std::back_inserter(code_)); file.close(); } //////////////////////////////////////////////////////////////////////////// template Function::Function(const cl::Context& a_context, const std::string& a_string) : code_policy(a_string), context_(a_context), vendor_id_(derive_vendor_id_from_context(&a_context)), devices_(a_context.getInfo()) { initialize(); } template void Function::clear_build_options() { build_options_.clear(); } template Function& Function::add_build_option(const std::string& an_option) { build_options_.push_back(an_option); return *this; } template Function& Function::add_build_option(const char *a_format_string, ...) { va_list argument_pointer; va_start(argument_pointer, a_format_string); build_options_.push_back(string_of_variable_arguments(a_format_string, argument_pointer)); va_end(argument_pointer); return *this; } template Function& Function::add_extension_macros_to_build_options(const cl::Device& a_device) { std::vector device_extensions; query_device_extensions(a_device, std::back_inserter(device_extensions)); for (auto x : device_extensions) { std::transform(x.begin(), x.end(), x.begin(), ::toupper); add_build_option(std::string("-DHAVE_EXTENSION_") + x); } return *this; } template void Function::build(const std::string& an_extra_build_option) { program_ = cl::Program(context_, cl::Program::Sources(1U, code_policy::source())); try { const cl_int error_code UNUSEDVAR = program_.build(devices_, build_options(an_extra_build_option).c_str()); #ifndef __CL_ENABLE_EXCEPTIONS if (error_code != CL_SUCCESS) { throw cl::Error(error_code); } #endif } catch (cl::Error& an_error) { throw ocl::runtime_error(an_error, build_log()); } } template void Function::build(const char *a_format_string, ...) { va_list argument_pointer; va_start(argument_pointer, a_format_string); build(string_of_variable_arguments(a_format_string, argument_pointer)); va_end(argument_pointer); } template std::vector Function::build_logs() const { std::vector logs; std::transform(devices_.begin(), devices_.end(), std::back_inserter(logs), [this] (cl::Device d) {return program_.getBuildInfo(d);}); return logs; } template std::string Function::build_log() const { return program_.getBuildInfo(devices_.front()); } template std::vector Function::binaries() const { std::vector sizes(program_.getInfo()); std::vector binaries(program_.getInfo()); std::vector results; results.resize(binaries.size()); auto s(sizes.begin()); auto r(results.begin()); for (auto b = binaries.begin(); b != binaries.end(); ++b, ++s, ++r) { r->reserve(*s); memcpy(&(*r)[0], *b, *s); } return results; } template BinaryPolicy::code_t Function::binary() const { return binaries().front(); } template const cl::Context& Function::context() const { return context_; } template vendor::id_t Function::vendor_id() const { return vendor_id_; } template const std::vector& Function::devices() const { return devices_; } template const cl::Device& Function::device() const { return devices_.front(); } template const cl::Program& Function::program() { return program_; } template cl::Kernel Function::create_kernel(const std::string& an_entry_point) { return cl::Kernel(program(), an_entry_point.c_str()); } template std::string Function::build_options(const std::string& an_extra_build_option) const { std::string options(concatenate(std::string(" "), build_options_.begin(), build_options_.end())); if (!an_extra_build_option.empty()) { options.append(" ").append(an_extra_build_option); } return options; } template void Function::add_queue(const cl::Device& a_device) { cl::CommandQueue queue(context_, a_device, default_queue_flags); queues_.push_back(queue); } template void Function::update_program_from_source(const cl::Program::Sources& a_source) { program_ = cl::Program(context(), a_source); } template void Function::initialize() { for (auto d : devices_) { queues_.push_back(cl::CommandQueue(context_, d, default_queue_flags)); } } template void Function::finalize() { for (auto q : queues_) { q.finish(); } } template class Function; template class Function; namespace hash { static std::hash function; inline static size_t of_string(const std::string& a_string) { return function(a_string.c_str()); } } // namespace hash template LazyFunction::LazyFunction(const cl::Context& a_context, const std::string& a_string) : super(a_context, a_string), build_completed_(false), text_hash_(size_t()), build_option_hash_(size_t()) {} static std::string format_build_diagnostics(const std::string& a_source_filename, const cl::Program& a_program, const cl::Device& a_device) { std::ostringstream message; #ifdef DEBUG cl_build_status build_status {cl_build_status()}; a_program.getBuildInfo(a_device, CL_PROGRAM_BUILD_STATUS, &build_status); message << "build status\n "; switch (build_status) { case CL_BUILD_NONE: message << "nothing done yet"; break; case CL_BUILD_ERROR: message << "error"; break; case CL_BUILD_SUCCESS: message << "success"; break; case CL_BUILD_IN_PROGRESS: message << "build currently in progress"; break; default: message << "other"; break; } message << " (status-code = " << build_status << ")\n"; #endif std::string build_info; a_program.getBuildInfo(a_device, CL_PROGRAM_BUILD_OPTIONS, &build_info); message << "build options\n " << build_info << "\n"; build_info.clear(); a_program.getBuildInfo(a_device, CL_PROGRAM_BUILD_LOG, &build_info); message << "build log\n"; auto is_source_file_location = [](const std::string& s) {return !s.empty() && s[0] == ':';}; auto is_internal_location = [](const std::string& s) {return !s.find(":");}; const std::string indentation(4U, ' '); std::vector diagnostics = split_string(build_info, '\n', true); for (auto d : diagnostics) { if (is_source_file_location(d)) { message << indentation << a_source_filename; } else if (is_internal_location(d)) { // Location already carries an "internal"-marker // string in lieu of a source filename. message << indentation; } else { message << indentation << indentation; } message << d << "\n"; } return message.str(); } template void LazyFunction::build(const std::string& an_extra_build_option) { if (!needs_building(an_extra_build_option)) { return; } cl::Program::Sources source(1U, code_policy::source()); super::update_program_from_source(source); try { // Implementation Note: Pass `this' to recover the // actual instance when class-static function // notify_trampoline() gets called. The trampoline // just invokes method notify(). super::program().build(std::vector(1U, super::device()), super::build_options(an_extra_build_option).c_str(), notify_trampoline, this); update_hashes(an_extra_build_option); } catch (cl::Error& an_error) { throw ocl::runtime_error(an_error, format_build_diagnostics(code_policy::filename(), program(), super::device())); } } template void LazyFunction::notify_trampoline(cl_program a_program, void* an_instance) { typedef LazyFunction self_t; self_t* self = static_cast(an_instance); // Recover pointer to instance. self->notify(a_program); } template void LazyFunction::update_hashes(const std::string& an_extra_build_option) { text_hash_ = hash::of_string(code_policy::text()); build_option_hash_ = hash::of_string(super::build_options(an_extra_build_option)); } template bool LazyFunction::needs_building(const std::string& an_extra_build_option) { return text_hash_ != hash::of_string(code_policy::text()) || build_option_hash_ != hash::of_string(super::build_options(an_extra_build_option)); } template LazyFunctionCXX::LazyFunctionCXX(const cl::Context& a_context, const std::string& a_string) : super(a_context, a_string) {} template void LazyFunctionCXX::wait() { std::unique_lock lock(build_completed_mutex_); // Anticipated Change: Replace the following lines with // build_completed_condition_.wait(lock, super::build_completed()) // when g++ does not fail with an ICE anymore. while (!super::build_completed()) { build_completed_condition_.wait(lock); } } template bool LazyFunctionCXX::build_completed() { std::lock_guard lock(build_completed_mutex_); return super::build_completed(); } template void LazyFunctionCXX::notify(cl_program a_program UNUSEDVAR) { build_completed_mutex_.lock(); super::set_build_completed(true); build_completed_mutex_.unlock(); build_completed_condition_.notify_all(); } template class LazyFunctionCXX; template class LazyFunctionCXX; void BatchBuilder::submit(value_t a_function, const char *a_format_string, ...) { va_list argument_pointer; va_start(argument_pointer, a_format_string); submit(a_function, string_of_variable_arguments(a_format_string, argument_pointer)); va_end(argument_pointer); } void SerialBatchBuilder::submit(value_t a_function, const std::string& a_build_option) { if (a_function) { try { a_function->build(a_build_option); a_function->wait(); } catch (ocl::runtime_error& error) { std::cerr << "error while compiling OpenCL kernel\n" << error.what() << "\n" << error.additional_message() << std::endl; } } #ifdef DEBUG else { std::cerr << "+ SerialBatchBuilder::submit: silently ignoring null-function\n"; } #endif } ThreadedBatchBuilder::ThreadedBatchBuilder() : run_(true) { std::thread builder(build_all_trampoline, this); builder.detach(); } ThreadedBatchBuilder::~ThreadedBatchBuilder() { finalize(); } void ThreadedBatchBuilder::submit(value_t a_function, const std::string& a_build_option) { assert(run_); if (a_function) { std::unique_lock lock(queue_mutex_); compile_queue_.push_front(BuildCommand(a_function, a_build_option)); queue_not_empty_.notify_one(); } #ifdef DEBUG else { std::cerr << "+ ThreadedBatchBuilder::submit: silently ignoring null-function\n"; } #endif } void ThreadedBatchBuilder::finalize() { run_ = false; } void ThreadedBatchBuilder::build_all_trampoline(ThreadedBatchBuilder* self) { self->build_all(); } void ThreadedBatchBuilder::build() { queue_mutex_.lock(); if (compile_queue_.empty()) { #ifdef DEBUG std::cerr << "+ ThreadedBatchBuilder::build -- spurious wake-up?\n"; #endif queue_mutex_.unlock(); return; } BuildCommand build_command(compile_queue_.back()); compile_queue_.pop_back(); queue_mutex_.unlock(); try { build_command.function->build(build_command.option); build_command.function->wait(); } catch (ocl::runtime_error& error) { std::cerr << "error while compiling OpenCL kernel\n" << error.what() << "\n" << error.additional_message() << std::endl; } } void ThreadedBatchBuilder::build_all() { while (run_) { std::unique_lock lock(queue_mutex_); while (compile_queue_.empty()) { queue_not_empty_.wait(lock); } build(); queue_mutex_.unlock(); } } #else #endif // OPENCL } // namespace ocl enblend-enfuse-4.2/src/openmp_vigra.h0000644000175000017500000007655212641706002014635 00000000000000/* * Copyright (C) 2013-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OPENMP_VIGRA_H_INCLUDED_ #define OPENMP_VIGRA_H_INCLUDED_ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include "openmp_def.h" namespace vigra { namespace omp { #ifdef OPENMP template inline void combineTwoImages(SrcImageIterator1 src1_upperleft, SrcImageIterator1 src1_lowerright, SrcAccessor1 src1_acc, SrcImageIterator2 src2_upperleft, SrcAccessor2 src2_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor& functor) { #pragma omp parallel { const vigra::Size2D size(src1_lowerright - src1_upperleft); Functor f(functor); #pragma omp for schedule(guided) nowait for (int y = 0; y < size.y; ++y) { const vigra::Diff2D begin(0, y); const vigra::Diff2D end(size.x, y + 1); vigra::combineTwoImages(src1_upperleft + begin, src1_upperleft + end, src1_acc, src2_upperleft + begin, src2_acc, dest_upperleft + begin, dest_acc, f); } } // omp parallel } template inline void combineTwoImagesIf(SrcImageIterator1 src1_upperleft, SrcImageIterator1 src1_lowerright, SrcAccessor1 src1_acc, SrcImageIterator2 src2_upperleft, SrcAccessor2 src2_acc, MaskImageIterator mask_upperleft, MaskAccessor mask_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor& functor) { #pragma omp parallel { const vigra::Size2D size(src1_lowerright - src1_upperleft); Functor f(functor); #pragma omp for schedule(guided) nowait for (int y = 0; y < size.y; ++y) { const vigra::Diff2D begin(0, y); const vigra::Diff2D end(size.x, y + 1); vigra::combineTwoImagesIf(src1_upperleft + begin, src1_upperleft + end, src1_acc, src2_upperleft + begin, src2_acc, mask_upperleft + begin, mask_acc, dest_upperleft + begin, dest_acc, f); } } // omp parallel } template inline void combineThreeImages(SrcImageIterator1 src1_upperleft, SrcImageIterator1 src1_lowerright, SrcAccessor1 src1_acc, SrcImageIterator2 src2_upperleft, SrcAccessor2 src2_acc, SrcImageIterator3 src3_upperleft, SrcAccessor3 src3_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor& functor) { #pragma omp parallel { const vigra::Size2D size(src1_lowerright - src1_upperleft); Functor f(functor); #pragma omp for schedule(guided) nowait for (int y = 0; y < size.y; ++y) { const vigra::Diff2D begin(0, y); const vigra::Diff2D end(size.x, y + 1); vigra::combineThreeImages(src1_upperleft + begin, src1_upperleft + end, src1_acc, src2_upperleft + begin, src2_acc, src3_upperleft + begin, src3_acc, dest_upperleft + begin, dest_acc, f); } } // omp parallel } template inline void copyImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc) { #pragma omp parallel { const vigra::Size2D size(src_lowerright - src_upperleft); #pragma omp for schedule(guided) nowait for (int y = 0; y < size.y; ++y) { const vigra::Diff2D begin(0, y); const vigra::Diff2D end(size.x, y + 1); vigra::copyImage(src_upperleft + begin, src_upperleft + end, src_acc, dest_upperleft + begin, dest_acc); } } // omp parallel } template inline void copyImageIf(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, MaskImageIterator mask_upperleft, MaskAccessor mask_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc) { #pragma omp parallel { const vigra::Size2D size(src_lowerright - src_upperleft); #pragma omp for schedule(guided) nowait for (int y = 0; y < size.y; ++y) { const vigra::Diff2D begin(0, y); const vigra::Diff2D end(size.x, y + 1); vigra::copyImageIf(src_upperleft + begin, src_upperleft + end, src_acc, mask_upperleft + begin, mask_acc, dest_upperleft + begin, dest_acc); } } // omp parallel } template inline void transformImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor& functor) { #pragma omp parallel { const vigra::Size2D size(src_lowerright - src_upperleft); Functor f(functor); #pragma omp for schedule(guided) nowait for (int y = 0; y < size.y; ++y) { const vigra::Diff2D begin(0, y); const vigra::Diff2D end(size.x, y + 1); vigra::transformImage(src_upperleft + begin, src_upperleft + end, src_acc, dest_upperleft + begin, dest_acc, f); } } // omp parallel } template inline void transformImageIf(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, MaskImageIterator mask_upperleft, MaskAccessor mask_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor& functor) { #pragma omp parallel { const vigra::Size2D size(src_lowerright - src_upperleft); Functor f(functor); #pragma omp for schedule(guided) nowait for (int y = 0; y < size.y; ++y) { const vigra::Diff2D begin(0, y); const vigra::Diff2D end(size.x, y + 1); vigra::transformImageIf(src_upperleft + begin, src_upperleft + end, src_acc, mask_upperleft + begin, mask_acc, dest_upperleft + begin, dest_acc, f); } } // omp parallel } namespace fh { namespace detail { template inline static ValueType square(ValueType x) { return x * x; } // Pedro F. Felzenszwalb, Daniel P. Huttenlocher // "Distance Transforms of Sampled Functions" template struct ChessboardTransform1D { typedef ValueType value_type; int id() const {return 0;} void operator()(ValueType* /* RESTRICT d */, const ValueType* /* RESTRICT f */, int /* n */) const { vigra_fail("fh::detail::ChessboardTransform1D: not implemented"); } }; template struct ManhattanTransform1D { typedef ValueType value_type; int id() const {return 1;} void operator()(ValueType* RESTRICT d, const ValueType* RESTRICT f, int n) const { const ValueType one = static_cast(1); d[0] = f[0]; for (int q = 1; q < n; ++q) { d[q] = std::min(f[q], d[q - 1] + one); } for (int q = n - 2; q >= 0; --q) { d[q] = std::min(d[q], d[q + 1] + one); } } }; template struct EuclideanTransform1D { typedef ValueType value_type; int id() const {return 2;} void operator()(ValueType* RESTRICT d, const ValueType* RESTRICT f, int n) const { typedef float math_t; const math_t infinity = std::numeric_limits::infinity(); int* v = static_cast(::omp::malloc(n * sizeof(int))); math_t* z = static_cast(::omp::malloc((n + 1) * sizeof(math_t))); int k = 0; v[0] = 0; z[0] = -infinity; z[1] = infinity; for (int q = 1; q < n; ++q) { const math_t sum_q = static_cast(f[q]) + square(static_cast(q)); math_t s = (sum_q - (f[v[k]] + square(v[k]))) / (2 * (q - v[k])); while (s <= z[k]) { --k; // IMPLEMENTATION NOTE // Prefetching improves performance because we must iterate from high to // low addresses, i.e. against the cache's look-ahead algorithm. HINTED_PREFETCH(z + k - 2U, PREPARE_FOR_READ, HIGH_TEMPORAL_LOCALITY); s = (sum_q - (f[v[k]] + square(v[k]))) / (2 * (q - v[k])); } ++k; v[k] = q; z[k] = s; z[k + 1] = infinity; } k = 0; for (int q = 0; q < n; ++q) { while (z[k + 1] < static_cast(q)) { ++k; } d[q] = square(q - v[k]) + f[v[k]]; } ::omp::free(z); ::omp::free(v); } }; template void fhDistanceTransform(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, DestImageIterator dest_upperleft, DestAccessor da, ValueType background, Transform1dFunctor transform1d) { typedef typename Transform1dFunctor::value_type DistanceType; typedef typename vigra::NumericTraits DistanceTraits; typedef vigra::BasicImage DistanceImageType; const vigra::Size2D size(src_lowerright - src_upperleft); const int greatest_length = std::max(size.x, size.y); DistanceImageType intermediate(size, vigra::SkipInitialization); #pragma omp parallel { DistanceType* const f = new DistanceType[greatest_length]; DistanceType* const d = new DistanceType[greatest_length]; DistanceType* const pf_end = f + size.y; const DistanceType* const pd_end = d + size.y; // IMPLEMENTATION NOTE // We need "guided" schedule to reduce the waiting time at the // (implicit) barriers. This holds true for the next OpenMP // parallelized "for" loop, too. #pragma omp for schedule(guided) for (int x = 0; x < size.x; ++x) { SrcImageIterator si(src_upperleft + vigra::Diff2D(x, 0)); for (DistanceType* pf = f; pf != pf_end; ++pf) { *pf = EXPECT_RESULT(sa(si) == background, false) ? DistanceTraits::max() : DistanceTraits::zero(); ++si.y; } transform1d(d, f, size.y); typename DistanceImageType::column_iterator ci(intermediate.columnBegin(x)); for (const DistanceType* pd = d; pd != pd_end; ++pd) { *ci = *pd; ++ci; // IMPLEMENTATION NOTE // Prefetching about halves the number of stalls per instruction of this loop. HINTED_PREFETCH(ci.operator->(), PREPARE_FOR_WRITE, HIGH_TEMPORAL_LOCALITY); } } #pragma omp for nowait schedule(guided) for (int y = 0; y < size.y; ++y) { transform1d(d, &intermediate(0, y), size.x); DestImageIterator i(dest_upperleft + vigra::Diff2D(0, y)); if (transform1d.id() == 2) { for (DistanceType* pd = d; pd != d + size.x; ++pd, ++i.x) { da.set(sqrt(*pd), i); } } else { for (DistanceType* pd = d; pd != d + size.x; ++pd, ++i.x) { da.set(*pd, i); } } } delete [] d; delete [] f; } // omp parallel } } // namespace detail } // namespace fh template void distanceTransform(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, DestImageIterator dest_upperleft, DestAccessor da, ValueType background, int norm) { switch (norm) { case 0: fh::detail::fhDistanceTransform(src_upperleft, src_lowerright, sa, dest_upperleft, da, background, fh::detail::ChessboardTransform1D()); break; case 1: fh::detail::fhDistanceTransform(src_upperleft, src_lowerright, sa, dest_upperleft, da, background, fh::detail::ManhattanTransform1D()); break; case 2: // FALLTHROUGH default: fh::detail::fhDistanceTransform(src_upperleft, src_lowerright, sa, dest_upperleft, da, background, fh::detail::EuclideanTransform1D()); } } #else template inline void combineTwoImages(SrcImageIterator1 src1_upperleft, SrcImageIterator1 src1_lowerright, SrcAccessor1 src1_acc, SrcImageIterator2 src2_upperleft, SrcAccessor2 src2_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor& func) { vigra::combineTwoImages(src1_upperleft, src1_lowerright, src1_acc, src2_upperleft, src2_acc, dest_upperleft, dest_acc, func); } template inline void combineTwoImagesIf(SrcImageIterator1 src1_upperleft, SrcImageIterator1 src1_lowerright, SrcAccessor1 src1_acc, SrcImageIterator2 src2_upperleft, SrcAccessor2 src2_acc, MaskImageIterator mask_upperleft, MaskAccessor mask_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor& func) { vigra::combineTwoImagesIf(src1_upperleft, src1_lowerright, src1_acc, src2_upperleft, src2_acc, mask_upperleft, mask_acc, dest_upperleft, dest_acc, func); } template inline void combineThreeImages(SrcImageIterator1 src1_upperleft, SrcImageIterator1 src1_lowerright, SrcAccessor1 src1_acc, SrcImageIterator2 src2_upperleft, SrcAccessor2 src2_acc, SrcImageIterator3 src3_upperleft, SrcAccessor3 src3_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor& func) { vigra::combineThreeImages(src1_upperleft, src1_lowerright, src1_acc, src2_upperleft, src2_acc, src3_upperleft, src3_acc, dest_upperleft, dest_acc, func); } template inline void copyImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc) { vigra::copyImage(src_upperleft, src_lowerright, src_acc, dest_upperleft, dest_acc); } template inline void copyImageIf(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, MaskImageIterator mask_upperleft, MaskAccessor mask_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc) { vigra::copyImageIf(src_upperleft, src_lowerright, src_acc, mask_upperleft, mask_acc, dest_upperleft, dest_acc); } template inline void transformImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor& func) { vigra::transformImage(src_upperleft, src_lowerright, src_acc, dest_upperleft, dest_acc, func); } template inline void transformImageIf(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, MaskImageIterator mask_upperleft, MaskAccessor mask_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor& func) { vigra::transformImageIf(src_upperleft, src_lowerright, src_acc, mask_upperleft, mask_acc, dest_upperleft, dest_acc, func); } template void distanceTransform(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, ValueType background, int norm) { vigra::distanceTransform(src_upperleft, src_lowerright, src_acc, dest_upperleft, dest_acc, background, norm); } #endif // OPENMP // // Argument Object Factory versions // template inline void combineTwoImages(vigra::triple src1, vigra::pair src2, vigra::pair dest, const Functor& functor) { vigra::omp::combineTwoImages(src1.first, src1.second, src1.third, src2.first, src2.second, dest.first, dest.second, functor); } template inline void combineTwoImagesIf(vigra::triple src1, vigra::pair src2, vigra::pair mask, vigra::pair dest, const Functor& functor) { vigra::omp::combineTwoImagesIf(src1.first, src1.second, src1.third, src2.first, src2.second, mask.first, mask.second, dest.first, dest.second, functor); } template inline void combineThreeImages(vigra::triple src1, vigra::pair src2, vigra::pair src3, vigra::pair dest, const Functor& functor) { vigra::omp::combineThreeImages(src1.first, src1.second, src1.third, src2.first, src2.second, src3.first, src3.second, dest.first, dest.second, functor); } template inline void transformImage(vigra::triple src, vigra::pair dest, const Functor& functor) { vigra::omp::transformImage(src.first, src.second, src.third, dest.first, dest.second, functor); } template inline void copyImage(vigra::triple src, vigra::pair dest) { vigra::omp::copyImage(src.first, src.second, src.third, dest.first, dest.second); } template inline void copyImageIf(vigra::triple src, vigra::pair mask, vigra::pair dest) { vigra::omp::copyImageIf(src.first, src.second, src.third, mask.first, mask.second, dest.first, dest.second); } template inline void transformImageIf(vigra::triple src, vigra::pair mask, vigra::pair dest, const Functor& functor) { vigra::omp::transformImageIf(src.first, src.second, src.third, mask.first, mask.second, dest.first, dest.second, functor); } template inline void distanceTransform(vigra::triple src, vigra::pair dest, ValueType background, int norm) { vigra::omp::distanceTransform(src.first, src.second, src.third, dest.first, dest.second, background, norm); } } // namespace omp } // namespace vigra #endif // OPENMP_VIGRA_H_INCLUDED_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/filespec.h0000644000175000017500000000700612641706002013725 00000000000000/* * Copyright (C) 2009-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FILESPEC_H_ #define FILESPEC_H_ #include #include #include "selector.h" #define RESPONSE_FILE_PREFIX_CHAR '@' //< response-file-prefix-char \char64 #define RESPONSE_FILE_COMMENT_CHAR '#' //< response-file-comment-char \char35 #define WHITESPACE_CHARS "\n\r\t " namespace enblend { typedef std::list FileNameList; typedef std::pair FilePosition; /** Filename, line number pairs */ typedef std::list FilePositionTrace; /** Traceback to a file position */ class TraceableFileName { public: TraceableFileName() = delete; TraceableFileName(const std::string& a_filename, const FilePositionTrace& a_trace, selector::Abstract* a_selector); virtual ~TraceableFileName(); virtual TraceableFileName* clone() const; const std::string& filename() const; const FilePositionTrace& trace() const; void unroll_trace() const; selector::Abstract* selector() const; protected: selector::Abstract* selector_; const std::string filename_; const FilePositionTrace trace_; }; class TraceableFileNameAndLayer : public TraceableFileName { typedef TraceableFileName super; public: TraceableFileNameAndLayer() = delete; TraceableFileNameAndLayer(const std::string& a_filename, const FilePositionTrace& a_trace, const std::string& a_layer_specification); TraceableFileNameAndLayer(const TraceableFileNameAndLayer&); TraceableFileNameAndLayer& operator=(const TraceableFileNameAndLayer&) = delete; ~TraceableFileNameAndLayer() override; TraceableFileNameAndLayer* clone() const override; std::string layer_spec() const; protected: const std::string layer_specification_; }; typedef std::list TraceableFileNameList; /** */ /** Recursively unfold filename which may be a literal name or a * response file. The result is a list of only literal * filenames. */ void unfold_filename(TraceableFileNameList& result, const std::string& filename); /** Answer whether we suspect filename is a response file. */ bool maybe_response_file(const std::string& filename); /** List of algorithm name / algorithm description pairs */ typedef std::list > algorithm_list; /** Answer a list of all globbing algorithms including aliases * that are known, i.e., have been compiled in. */ algorithm_list known_globbing_algorithms(); } #endif // FILESPEC_H_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/parameter.h0000644000175000017500000001013412641706002014107 00000000000000/* * Copyright (C) 2015, 2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PARAMETER_H_INCLUDED #define PARAMETER_H_INCLUDED #include #include namespace parameter { // Identifier: [A-Za-z][A-Za-z0-9_-]* bool is_valid_identifier(const std::string& an_identifier); void insert(const std::string& a_key, const std::string& a_value); void erase(const std::string& a_key); void erase_all(); struct not_found : public std::runtime_error { explicit not_found(const std::string& a_message) : std::runtime_error(a_message) {} }; struct conversion_error : public std::runtime_error { explicit conversion_error(const std::string& a_message) : std::runtime_error(a_message) {} }; // NOTES // // * The access of parameters through parameter::as_* is // reasonably fast. For time-critical parts of the code, the // parameter's value can always be copied into a local variable. // // * The map from parameter keys to values is meant to be constant // after the command line was parsed, i.e. neither the map // itself, nor one of its values should be modified. Following // this convention makes all parameter::as_* functions thread // safe. // // Some examples how to use parameters: // // (1) Check whether a parameter has been set. // if (parameter::exists("foobar")) {...} // else {...} // // (2) Use a parameter that is known to exist. // std::string s = parameter::as_string("foobar"); // int i = parameter::as_integer("foobar"); // unsigned u = parameter::as_unsigned("foobar"); // double x = parameter::as_floating_point("foobar"); // bool b = parameter::as_boolean("foobar"); // // (3) Substitute parameter value if it exists; otherwise go with // the default. // std::string s = parameter::as_string("foobar", "baz"); // int i = parameter::as_integer("foobar", 123); // unsigned u = parameter::as_unsigned("foobar", 42U); // double x = parameter::as_floating_point("foobar", 0.577215665); // bool b = parameter::as_boolean("foobar", true); // // (4) React on parameter with a non-local change of control flow // int i; // try {i = parameter::as_integer("foobar");} // catch (parameter::not_found&) {...} // // A parameter always can be retrieved as string with function // as_string(). All other as_* functions throw the exception // conversion_error, if the parameter's value cannot be // represented. bool exists(const std::string& a_key); std::string as_string(const std::string& a_key); std::string as_string(const std::string& a_key, const std::string& a_default_value); int as_integer(const std::string& a_key); int as_integer(const std::string& a_key, int a_default_value); unsigned as_unsigned(const std::string& a_key); unsigned as_unsigned(const std::string& a_key, unsigned a_default_value); double as_double(const std::string& a_key); double as_double(const std::string& a_key, double a_default_value); bool as_boolean(const std::string& a_key); bool as_boolean(const std::string& a_key, bool a_default_value); } // namespace parameter #endif // PARAMETER_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/mersenne.h0000644000175000017500000000347312641706002013753 00000000000000/* * Copyright (C) 2015, 2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef MERSENNE_H_INCLUDED_ #define MERSENNE_H_INCLUDED_ #ifdef HAVE_CONFIG_H #include #endif #include class MersenneTwister { public: typedef unsigned long result_type; MersenneTwister(); MersenneTwister(const MersenneTwister& another_generator); virtual ~MersenneTwister(); MersenneTwister& operator=(const MersenneTwister& another_generator); result_type min() const {return gsl_rng_min(generator_);} result_type max() const {return gsl_rng_max(generator_);} void seed(); void seed(result_type a_seed); result_type operator()() {return gsl_rng_get(generator_);} private: gsl_rng* generator_; }; // class MersenneTwister class UniformMersenneTwister : public MersenneTwister { public: void non_deterministic_seed(); result_type get() {return this->operator()();} double get_uniform() {return static_cast(get()) / static_cast(max());} }; // class UniformMersenneTwister #endif // MERSENNE_H_INCLUDED_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/mask.h0000644000175000017500000016265612641706002013103 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef MASK_H_INCLUDED_ #define MASK_H_INCLUDED_ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "fillpolygon.hxx" #include "rect2d.hxx" #include "stride.hxx" #include "common.h" #include "anneal.h" #include "muopt.h" #include "nearest.h" #include "parameter.h" #include "path.h" #include "postoptimizer.h" #include "graphcut.h" #include "maskcommon.h" #include "masktypedefs.h" using vigra::functor::Arg1; using vigra::functor::Arg2; using vigra::functor::Arg3; using vigra::functor::ifThenElse; using vigra::functor::Param; using vigra::functor::UnaryFunctor; std::string stringOfPixelDifferenceFunctor(difference_functor_t aFunctor) { switch (aFunctor) { case HueLuminanceMaxDifference: return "maximum-hue-luminance"; case DeltaEDifference: return "delta-e"; default: NEVER_REACHED("switch control expression \"aFunctor\" out of range"); } return "unknown"; } namespace enblend { void dump_segment(const Segment& segment, const std::string& prefix = std::string(), std::ostream& out = std::cout) { const unsigned points_per_line = 5U; unsigned n = 1U; const size_t size = segment.size(); out << prefix << "{segment with " << size << " point(s): // suffix 'f' means frozen point\n" << prefix; for (Segment::const_iterator i = segment.begin(); i != segment.end(); ++i, ++n) { // Append an 'f' to non-movable ("frozen") segment points. out << ' ' << i->second << (i->first ? ' ' : 'f'); if (n % points_per_line == 0U && n != size) { out << '\n' << prefix; } } out << "\n" << prefix << "}\n"; } void dump_contour(const Contour& contour, const std::string& prefix = std::string(), std::ostream& out = std::cout) { out << prefix << "{contour with " << contour.size() << " segment(s):\n"; for (Contour::const_iterator i = contour.begin(); i != contour.end(); ++i) { dump_segment(**i, prefix + " ", out); } out << prefix << "}\n"; } void dump_contourvector(const ContourVector& contourvector, const std::string& prefix = std::string(), std::ostream& out = std::cout) { out << prefix << "{contourvector with " << contourvector.size() << " contour(s):\n"; for (ContourVector::const_iterator i = contourvector.begin(); i != contourvector.end(); ++i) { dump_contour(**i, prefix + " ", out); } out << prefix << "}\n"; } template void visualizePoint(ImageType& image, const vigra::Point2D& location, typename ImageType::PixelType value) { typedef typename ImageType::Iterator Iterator; Iterator point(image.upperLeft() + location); if (point.x >= image.upperLeft().x && point.x < image.lowerRight().x && point.y >= image.upperLeft().y && point.y < image.lowerRight().y) { image.accessor().set(value, point); } } template inline T round_to(double x) { return static_cast(x >= 0.0 ? x + 0.5 : x - 0.5); } template void visualizePoint(ImageType& image, const vigra::Point2D& location, typename ImageType::PixelType value, marker_t marker, int radius) { if (radius <= 0) { return; } const int r_sqrt2 = round_to(static_cast(radius) / 1.414213562373095); switch (marker) { case NO_MARKER: return; case DOT_MARKER: visualizePoint(image, location, value); break; case PLUS_MARKER: for (int i = -radius; i <= radius; ++i) { visualizePoint(image, location + vigra::Point2D(i, 0), value); visualizePoint(image, location + vigra::Point2D(0, i), value); } break; case CROSS_MARKER: for (int i = -r_sqrt2; i <= r_sqrt2; ++i) { visualizePoint(image, location + vigra::Point2D(i, i), value); visualizePoint(image, location + vigra::Point2D(-i, i), value); } break; case HOLLOW_SQUARE_MARKER: for (int i = -r_sqrt2; i <= r_sqrt2; ++i) { visualizePoint(image, location + vigra::Point2D(-r_sqrt2, i), value); visualizePoint(image, location + vigra::Point2D(r_sqrt2, i), value); visualizePoint(image, location + vigra::Point2D(i, -r_sqrt2), value); visualizePoint(image, location + vigra::Point2D(i, r_sqrt2), value); } break; case HOLLOW_DIAMOND_MARKER: for (int i = 0; i <= radius; ++i) { visualizePoint(image, location + vigra::Point2D(i - radius, i), value); visualizePoint(image, location + vigra::Point2D(i, i - radius), value); visualizePoint(image, location + vigra::Point2D(-i + radius, i), value); visualizePoint(image, location + vigra::Point2D(-i, i - radius), value); } break; default: visualizePoint(image, location, value); } } // Draw a line from begin to end in image. Use value as pixel color. // // The algorithm is not implemented efficiently. However, the // function is only called to visualize the initial seam line, which // we do not consider a performance-critical job. template void visualizeLine(ImageType& image, const vigra::Point2D& begin, const vigra::Point2D& end, typename ImageType::PixelType value) { typedef typename ImageType::Iterator Iterator; const vigra::Diff2D difference(end - begin); const int stepX = sign(difference.x); const int stepY = sign(difference.y); Iterator point(image.upperLeft() + begin); const Iterator stop(image.upperLeft() + end); double error = 0.0; //std::cout << "+ [" << begin << " .. " << end << "]\n"; const vigra::Size2D size(image.size()); // Exit immediately if both start point and end point are outside of the image. if (!(begin.x >= 0 && begin.x < size.x && begin.y >= 0 && begin.y < size.y && end.x >= 0 && end.x < size.x && end.y >= 0 && end.y < size.y)) { return; } if (abs(difference.x) >= abs(difference.y)) { const double delta_error = difference.x == 0 ? 0.0 : fabs(static_cast(difference.y) / static_cast(difference.x)); while (true) { if (point.x >= image.upperLeft().x && point.x < image.lowerRight().x && point.y >= image.upperLeft().y && point.y < image.lowerRight().y) { image.accessor().set(value, point); } if (point.x == stop.x) { break; } error += delta_error; if (fabs(error) >= 0.5) { point.y += stepY; error -= 1.0; } point.x += stepX; } } else { const double delta_error = difference.y == 0 ? 0.0 : fabs(static_cast(difference.x) / static_cast(difference.y)); while (true) { if (point.x >= image.upperLeft().x && point.x < image.lowerRight().x && point.y >= image.upperLeft().y && point.y < image.lowerRight().y) { image.accessor().set(value, point); } if (point.y == stop.y) { break; } error += delta_error; if (fabs(error) >= 0.5) { point.x += stepX; error -= 1.0; } point.y += stepY; } } } template vertex_function for_each_vertex(ContourVector::iterator first, ContourVector::iterator last, vertex_function f) { for (ContourVector::iterator contour = first; contour != last; ++contour) { for (Contour::iterator segment = (*contour)->begin(); segment != (*contour)->end(); ++segment) { Segment* const snake = *segment; for (Segment::iterator vertex = snake->begin(); vertex != snake->end(); ++vertex) { f(vertex); } } } return f; } template class FindAverageAndVarianceIf { public: typedef value argument_type; typedef value first_argument_type; typedef double second_argument_type; typedef typename vigra::NumericTraits::RealPromote result_type; typedef typename vigra::NumericTraits::RealPromote value_type; explicit FindAverageAndVarianceIf(predicate aPredicate) : sum_(0.0), sum_of_squares_(0.0), count_(0.0), pred_(aPredicate) {} void reset() { count_ = 0.0; sum_of_squares_ = 0.0; count_ = 0.0; } void operator()(const argument_type& v) { if (pred_(v)) { count_ += 1.0; sum_ += static_cast(v); sum_of_squares_ += square(static_cast(v)); } } unsigned count() const {return static_cast(count_);} result_type average() const { assert(count_ != 0.0); return static_cast(sum_ / count_); } result_type variance() const { assert(count_ != 0.0); return static_cast((sum_of_squares_ - square(sum_) / count_) / count_); } private: double sum_; double sum_of_squares_; double count_; predicate pred_; }; template class XorAccessor { public: typedef ValueType value_type; typedef AccessorType accessor_type; explicit XorAccessor(AccessorType a) : acc(a) {} template ValueType operator()(const Iterator& i) const {return acc(i);} ValueType operator()(const ValueType* i) const {return acc(i);} template ValueType operator()(const Iterator& i, Difference d) const {return acc(i, d);} template void set(const Value& v, const Iterator& i) const {acc.set(v ^ acc(i), i);} template void set(const Value& v, Iterator& i) const {acc.set(v ^ acc(i), i);} template void set(const Value& v, const Iterator& i, const Difference& d) const {acc.set(v ^ acc(i, d), i, d);} private: AccessorType acc; }; template void closedPolygonsOfContourSegments(const vigra::Size2D& mask_size, const Contour& contour, BackInsertionIterator result) { #ifdef DEBUG_POLYGON_FILL const vigra::Diff2D border(10, 10); vigra::BRGBImage polygon_image(mask_size + border + border); visualizeLine(polygon_image, vigra::Point2D(0, 0) + border, vigra::Point2D(mask_size.x, 0) + border, VISUALIZE_RGB_COLOR_GREEN3); visualizeLine(polygon_image, vigra::Point2D(mask_size.x, 0) + border, vigra::Point2D(mask_size.x, mask_size.y) + border, VISUALIZE_RGB_COLOR_GREEN3); visualizeLine(polygon_image, vigra::Point2D(mask_size.x, mask_size.y) + border, vigra::Point2D(0, mask_size.y) + border, VISUALIZE_RGB_COLOR_GREEN3); visualizeLine(polygon_image, vigra::Point2D(0, mask_size.y) + border, vigra::Point2D(0, 0) + border, VISUALIZE_RGB_COLOR_GREEN3); std::cout << "+ closedPolygonsOfContourSegments: #segments = " << contour.size() << "\n"; #endif vigra::Point2D last_point; for (Contour::const_iterator segment = contour.begin(); segment != contour.end(); ++segment) { const Segment::iterator vertex_begin((*segment)->begin()); const Segment::iterator vertex_end((*segment)->end()); for (Segment::iterator vertex = vertex_begin; vertex != vertex_end; ++vertex) { last_point = vigra::Point2D(vertex->second.x, vertex->second.y); *result++ = last_point; } #ifdef DEBUG_POLYGON_FILL std::cout << "+ closedPolygonsOfContourSegments: #vertices = " << (*segment)->size() << "\n"; Segment::iterator previous_vertex; for (Segment::iterator vertex = vertex_begin; vertex != vertex_end; ++vertex) { const vigra::Point2D p(vertex->second.x, vertex->second.y); if (vertex != vertex_begin) { const vigra::Point2D q(previous_vertex->second.x, previous_vertex->second.y); visualizeLine(polygon_image, q + border, p + border, VISUALIZE_RGB_COLOR_MAGENTA2); } previous_vertex = vertex; visualizePoint(polygon_image, p + border, VISUALIZE_RGB_COLOR_RED1); } #endif } const Segment::iterator firstVertex((*(contour.begin()))->begin()); const vigra::Point2D first_point(firstVertex->second.x, firstVertex->second.y); if (first_point != last_point) { *result++ = first_point; } *result++ = END_OF_SEGMENT_MARKER; #ifdef DEBUG_POLYGON_FILL vigra::exportImage(srcImageRange(polygon_image), vigra::ImageExportInfo(",polygon.tif")); #endif } template void fillContourScanLine(MaskType* mask, const Contour& contour, const vigra::Diff2D& offset) { typedef typename MaskType::PixelType MaskPixelType; typedef typename MaskType::Accessor MaskAccessor; const vigra::Size2D mask_size(mask->lowerRight() - mask->upperLeft()); std::vector polygon; closedPolygonsOfContourSegments(mask_size, contour, std::back_inserter(polygon)); vigra_ext::fill_polygon(mask->upperLeft() + offset, mask->lowerRight() + offset, XorAccessor(mask->accessor()), polygon.begin(), polygon.end(), ~MaskPixelType()); } template void fillContourScanLineActive(MaskType* mask, const Contour& contour, const vigra::Diff2D& offset) { typedef typename MaskType::PixelType MaskPixelType; typedef typename MaskType::Accessor MaskAccessor; const vigra::Size2D mask_size(mask->lowerRight() - mask->upperLeft()); std::vector polygon; closedPolygonsOfContourSegments(mask_size, contour, std::back_inserter(polygon)); vigra_ext::fill_polygon_active(mask->upperLeft() + offset, mask->lowerRight() + offset, XorAccessor(mask->accessor()), polygon.begin(), polygon.end(), ~MaskPixelType()); } template void fillContour(MaskType* mask, const Contour& contour, const vigra::Diff2D& offset) { const std::string routine_name(parameter::as_string("polygon-filler", "new-active")); #ifdef DEBUG_POLYGON_FILL std::cout << "+ fillContour: mask offset = " << offset << "\n"; #endif if (routine_name == "new") { #ifdef DEBUG_POLYGON_FILL std::cout << "+ fillContour: use fillContourScanLine polygon filler\n"; #endif fillContourScanLine(mask, contour, offset); } else { #ifdef DEBUG_POLYGON_FILL std::cout << "+ fillContour: use fillContourScanLineActive polygon filler\n"; #endif fillContourScanLineActive(mask, contour, offset); } } template void maskBounds(MaskType* mask, const vigra::Rect2D& uBB, vigra::Rect2D& mBB) { typedef typename MaskType::PixelType MaskPixelType; typedef typename MaskType::traverser MaskIteratorType; // Find the bounding box of the mask transition line and put it in mBB. // mBB starts out as empty rectangle. mBB = vigra::Rect2D(vigra::Point2D(mask->size()), vigra::Point2D(0, 0)); MaskIteratorType myPrev = mask->upperLeft(); MaskIteratorType my = mask->upperLeft() + vigra::Diff2D(0, 1); MaskIteratorType mend = mask->lowerRight(); MaskIteratorType mxLeft = myPrev; MaskIteratorType mx = myPrev + vigra::Diff2D(1, 0); for (int x = 1; mx.x < mend.x; ++x, ++mx.x, ++mxLeft.x) { if (*mxLeft != *mx) { mBB |= vigra::Rect2D(x - 1, 0, x + 1, 1); } } for (int y = 1; my.y < mend.y; ++y, ++my.y, ++myPrev.y) { mxLeft = my; mx = my + vigra::Diff2D(1, 0); MaskIteratorType mxUpLeft = myPrev; MaskIteratorType mxUp = myPrev + vigra::Diff2D(1, 0); if (*mxUpLeft != *mxLeft) { // Transition line is between mxUpLeft and mxLeft. mBB |= vigra::Rect2D(0, y - 1, 1, y + 1); } for (int x = 1; mx.x < mend.x; ++x, ++mx.x, ++mxLeft.x, ++mxUp.x) { if (*mxLeft != *mx) { mBB |= vigra::Rect2D(x - 1, y, x + 1, y + 1); } if (*mxUp != *mx) { mBB |= vigra::Rect2D(x, y - 1, x + 1, y + 1); } } } // Check that mBB is well-defined. if (mBB.isEmpty()) { // No transition pixels were found in the mask at all. This // means that one image has no contribution. if (*(mask->upperLeft()) == vigra::NumericTraits::zero()) { // If the mask is entirely black, then inspectOverlap // should have caught this. It should have said that the // white image is redundant. std::cerr << command << ": mask is entirely black, but white image was not identified as redundant" << std::endl; exit(1); } else { // If the mask is entirely white, then the black image // would have been identified as redundant if black and // white were swapped. Set mBB to the full size of the // mask. mBB = uBB; // Explain why the black image disappears completely. std::cerr << command << ": warning: previous images are completely overlapped by the current images" << std::endl; } } else { // mBB is defined relative to inputUnion origin //std::cerr << command << ": info: mBB relative to mask: " << mBB << std::endl; mBB.moveBy(uBB.upperLeft()); } if (Verbose >= VERBOSE_ROIBB_SIZE_MESSAGES) { std::cerr << command << ": info: mask transition line bounding box: " << mBB << std::endl; } } // Answer whether a_point sits on the boundary of a_rectangle. inline static bool is_on_boundary(const vigra::Point2D& a_point, const vigra::Rect2D& a_rectangle) { return a_point.px() == a_rectangle.left() || a_point.px() == a_rectangle.right() || a_point.py() == a_rectangle.top() || a_point.py() == a_rectangle.bottom(); } // Answer whether a_point sits in one of the corners of a_rectangle. inline static bool is_in_corner(const vigra::Point2D& a_point, const vigra::Rect2D& a_rectangle) { return (a_point.px() == a_rectangle.left() || a_point.px() == a_rectangle.right()) && (a_point.py() == a_rectangle.top() || a_point.py() == a_rectangle.bottom()); } // Vectorize the seam line defined in nftOutputImage into the contour rawSegments. template void vectorizeSeamLine(Contour& rawSegments, const AlphaType* const whiteAlpha, const AlphaType* const blackAlpha, const vigra::Rect2D& uBB, int nftStride, MaskType* nftOutputImage, int vectorizeDistance = 0) { typedef typename MaskType::PixelType MaskPixelType; typedef typename MaskType::traverser MaskIteratorType; const double diagonalLength = hypot(static_cast(nftOutputImage->width()), static_cast(nftOutputImage->height())); if (vectorizeDistance == 0) { vectorizeDistance = MaskVectorizeDistance.is_percentage() ? static_cast(ceil(MaskVectorizeDistance.value() / 100.0 * diagonalLength)) : MaskVectorizeDistance.value(); } if (vectorizeDistance < minimumVectorizeDistance) { std::cerr << command << ": warning: mask vectorization distance " << vectorizeDistance << " (" << 100.0 * vectorizeDistance / diagonalLength << "% of diagonal) is smaller\n" << command << ": warning: than minimum of " << minimumVectorizeDistance << "; will use " << minimumVectorizeDistance << " (" << 100.0 * minimumVectorizeDistance / diagonalLength << "% of diagonal)" << std::endl; vectorizeDistance = minimumVectorizeDistance; } const MaskPixelType zero(vigra::NumericTraits::zero()); const MaskPixelType one(vigra::NumericTraits::one()); const vigra::Rect2D border(1, 1, nftOutputImage->width() - 1, nftOutputImage->height() - 1); MaskIteratorType my = nftOutputImage->upperLeft() + vigra::Diff2D(1, 1); MaskIteratorType mend = nftOutputImage->lowerRight() + vigra::Diff2D(-1, -1); for (int y = 1; my.y < mend.y; ++y, ++my.y) { MaskIteratorType mx = my; MaskPixelType lastColor = zero; for (int x = 1; mx.x < mend.x; ++x, ++mx.x) { if (*mx == vigra::NumericTraits::max() && lastColor == zero) { // Found the corner of a previously unvisited white region. // Create a Segment to hold the border of this region. Segment* snake = new Segment(); rawSegments.push_back(snake); std::vector excessPoints; // Walk around border of white region. vigra::CrackContourCirculator crack(mx); const vigra::CrackContourCirculator crackEnd(crack); bool lastPointFrozen = false; int distanceLastPoint = 0; do { const vigra::Point2D currentPoint = *crack + vigra::Diff2D(x, y); crack++; const vigra::Point2D nextPoint = *crack + vigra::Diff2D(x, y); // See if currentPoint lies on border. if (is_on_boundary(currentPoint, border)) { // See if currentPoint is in a corner. if (is_in_corner(currentPoint, border)) { snake->push_front(std::make_pair(false, currentPoint)); distanceLastPoint = 0; } else if (!lastPointFrozen || !is_on_boundary(nextPoint, border)) { snake->push_front(std::make_pair(false, currentPoint)); distanceLastPoint = 0; } else { excessPoints.push_back(currentPoint); } lastPointFrozen = true; } else { // Current point is not frozen. if (distanceLastPoint % vectorizeDistance == 0) { snake->push_front(std::make_pair(true, currentPoint)); distanceLastPoint = 0; } else { excessPoints.push_back(currentPoint); } lastPointFrozen = false; } distanceLastPoint++; } while (crack != crackEnd); // Paint the border so this region will not be found again. for (Segment::iterator vertexIterator = snake->begin(); vertexIterator != snake->end(); ++vertexIterator) { (*nftOutputImage)[vertexIterator->second] = one; // While we're at it, convert vertices to uBB-relative coordinates. vertexIterator->second = nftStride * (vertexIterator->second + vigra::Diff2D(-1, -1)); // While we're at it, mark vertices outside the union region as not moveable. if (vertexIterator->first && (*whiteAlpha)[vertexIterator->second + uBB.upperLeft()] == zero && (*blackAlpha)[vertexIterator->second + uBB.upperLeft()] == zero) { vertexIterator->first = false; } } // These are points on the border of the white region // that are not in the snake. Recolor them so that // this (white) region will not be found again. for (std::vector::iterator vertexIterator = excessPoints.begin(); vertexIterator != excessPoints.end(); ++vertexIterator) { (*nftOutputImage)[*vertexIterator] = one; } // Kill empty or single-point snakes right away. if (snake->size() <= 1U) { rawSegments.pop_back(); delete snake; } } lastColor = *mx; } } } /** Convert rawContours snakes into segments with unbroken runs of * moveable vertices. */ void reorderSnakesToMovableRuns(ContourVector& contours, const Contour& rawSegments) { for (Contour::const_iterator segments = rawSegments.begin(); segments != rawSegments.end(); ++segments) { Segment* snake = *segments; // Snake becomes multiple separate segments in one contour Contour* currentContour = new Contour(); contours.push_back(currentContour); // Check if snake is a closed contour bool closedContour = true; for (Segment::iterator vertexIterator = snake->begin(); vertexIterator != snake->end(); ++vertexIterator) { if (!vertexIterator->first) { closedContour = false; break; } } // Closed contours consist of only moveable vertices. if (closedContour) { currentContour->push_back(snake); continue; } if (snake->front().first) { // First vertex is moveable. Rotate list so that first // vertex is nonmoveable. Segment::iterator firstNonmoveableVertex = snake->begin(); while (firstNonmoveableVertex->first) { ++firstNonmoveableVertex; } // Copy initial run on moveable vertices and first // non-moveable vertex to end of list. Segment::iterator firstNonmoveableSuccessor = firstNonmoveableVertex; ++firstNonmoveableSuccessor; if (EXPECT_RESULT(firstNonmoveableSuccessor == snake->end(), false)) { snake->insert(std::next(firstNonmoveableVertex), snake->begin(), firstNonmoveableVertex); } else { snake->insert(snake->end(), // append at the end snake->begin(), firstNonmoveableSuccessor); } // Erase initial run of moveable vertices. snake->erase(snake->begin(), firstNonmoveableVertex); } // Find last moveable vertex. Segment::iterator lastMoveableVertex = snake->begin(); for (Segment::iterator vertexIterator = snake->begin(); vertexIterator != snake->end(); ++vertexIterator) { if (vertexIterator->first) { lastMoveableVertex = vertexIterator; } } Segment* currentSegment = nullptr; bool insideMoveableSegment = false; bool passedLastMoveableVertex = false; Segment::iterator lastNonmoveableVertex = snake->begin(); for (Segment::iterator vertexIterator = snake->begin(); vertexIterator != snake->end(); ++vertexIterator) { // Create a new segment if necessary. if (currentSegment == nullptr) { currentSegment = new Segment(); currentContour->push_back(currentSegment); } // Keep track of when we visit the last moveable vertex. // Don't create new segments after this point. // Add all remaining nonmoveable vertices to current segment. if (vertexIterator == lastMoveableVertex) { passedLastMoveableVertex = true; } // Keep track of last nonmoveable vertex. if (!vertexIterator->first) { lastNonmoveableVertex = vertexIterator; } // All segments must begin with a nonmoveable vertex. // If only one nonmoveable vertex separates two runs of moveable vertices, // that vertex is copied into the beginning of the current segment. // It was previously added at the end of the last segment. if (vertexIterator->first && currentSegment->empty()) { currentSegment->push_front(*lastNonmoveableVertex); } // Add the current vertex to the current segment. currentSegment->push_front(*vertexIterator); if (!insideMoveableSegment && vertexIterator->first) { // Beginning a new moveable segment. insideMoveableSegment = true; } else if (insideMoveableSegment && !vertexIterator->first && !passedLastMoveableVertex) { // End of currentSegment. insideMoveableSegment = false; // Correct for the push_fronts we've been doing currentSegment->reverse(); // Cause a new segment to be generated on next vertex. currentSegment = nullptr; } } // Reverse the final segment. if (currentSegment != nullptr) { currentSegment->reverse(); } delete snake; } } /** Find extent of moveable snake vertices, and vertices bordering * moveable vertices vertex bounding box. */ vigra::Rect2D vertexBoundingBox(ContourVector& contours) { vigra::Rect2D box; bool initializedVBB = false; for (ContourVector::iterator currentContour = contours.begin(); currentContour != contours.end(); ++currentContour) { for (Contour::iterator currentSegment = (*currentContour)->begin(); currentSegment != (*currentContour)->end(); ++currentSegment) { Segment::iterator lastVertex = (*currentSegment)->begin(); bool foundFirstMoveableVertex = false; for (Segment::iterator vertexIterator = (*currentSegment)->begin(); vertexIterator != (*currentSegment)->end(); ++vertexIterator) { if (vertexIterator->first) { if (!initializedVBB) { box = vigra::Rect2D(vertexIterator->second, vigra::Size2D(1, 1)); initializedVBB = true; } else { box |= vertexIterator->second; } if (!foundFirstMoveableVertex) { box |= lastVertex->second; } foundFirstMoveableVertex = true; } else if (foundFirstMoveableVertex) { // First nonmoveable vertex at end of run. box |= vertexIterator->second; break; } lastVertex = vertexIterator; } } } return box; } inline static int round_to_nearest_div(int a_numerator, int a_denominator) { const std::div_t result(std::div(a_numerator, a_denominator)); const int rem2 = 2 * result.rem; return rem2 >= a_denominator ? result.quot + 1 : (-rem2 >= a_denominator ? result.quot - 1 : result.quot); } template void search_for_isolated_points(const AlphaType* const alpha) { // ANTICIPATED CHANGE: We only take care of the inner part of the // image `alpha' because `vigra::NeighborhoodCirculator' does not // work on along the edges. If necessary the test can be extended // to the edges using `vigra::RestrictedNeighborhoodCirculator'. typedef typename AlphaType::const_traverser alpha_traverser; typedef vigra::NeighborhoodCirculator circulator; const alpha_traverser t_end(alpha->lowerRight() - vigra::Diff2D(1, 1)); const vigra::Size2D size(alpha->size()); unsigned number_of_isolated_points(0U); #ifdef OPENMP #pragma omp parallel for reduction(+: number_of_isolated_points) schedule(guided) #endif for (int row = 1; row < size.y - 1; ++row) { alpha_traverser t(alpha->upperLeft() + vigra::Diff2D(1, row)); for (t.x = 1; t.x != t_end.x; ++t.x) { if (*t == 0) { circulator c(t); const circulator c_end(c); while (true) { if (*c == 0) { break; } ++c; if (c == c_end) { ++number_of_isolated_points; break; } } } } } if (number_of_isolated_points >= std::max(1U, parameter::as_unsigned("black-alpha-mask-check-isolated-points-threshold", 2U))) { std::cerr << command << ": encountered degenerate image/mask geometry; too high risk of defective seam line" << std::endl; #ifdef DEBUG std::cerr << command << ": note: found " << number_of_isolated_points << " isolated points in black alpha mask" << std::endl; #endif exit(1); } } /** Calculate a blending mask between whiteImage and blackImage. */ template MaskType* createMask(const ImageType* const white, const ImageType* const black, const AlphaType* const whiteAlpha, const AlphaType* const blackAlpha, const vigra::Rect2D& uBB, const vigra::Rect2D& iBB, bool wraparound, unsigned numberOfImages, FileNameList::const_iterator inputFileNameIterator, unsigned m) { typedef typename ImageType::PixelType ImagePixelType; typedef typename MaskType::PixelType MaskPixelType; if (LoadMasks) { // Read mask from a file instead of calculating it. MaskType* mask = new MaskType(uBB.size()); const std::string maskFilename = enblend::expandFilenameTemplate(LoadMaskTemplate, numberOfImages, *inputFileNameIterator, OutputFileName, m); if (can_open_file(maskFilename)) { vigra::ImageImportInfo maskInfo(maskFilename.c_str()); if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << command << ": info: loading mask \"" << maskFilename << "\"" << std::endl; } if (!maskInfo.isGrayscale()) { std::cerr << command << ": mask image \"" << maskFilename << "\" is not grayscale" << std::endl; exit(1); } if (maskInfo.numExtraBands() != 0) { std::cerr << command << ": mask image \"" << maskFilename << "\" must not have an alpha channel" << std::endl; exit(1); } if (std::string(maskInfo.getPixelType()) != vigra::TypeAsString::result()) { std::cerr << command << ": mask image \"" << maskFilename << "\" has pixel type " << maskInfo.getPixelType() << ";\n" << command << ": note: expecting pixel type " << vigra::TypeAsString::result() << std::endl; exit(1); } if (maskInfo.width() != uBB.width() || maskInfo.height() != uBB.height()) { const bool too_small = maskInfo.width() < uBB.width() || maskInfo.height() < uBB.height(); std::string category; if (too_small) { category = "warning: "; } std::cerr << command << ": " << category << "mask in \"" << maskFilename << "\" has size " << "(" << maskInfo.width() << "x" << maskInfo.height() << "),\n" << command << ": " << category << " but image union has size " << uBB.size() << ";\n" << command << ": " << category << " make sure this is the right mask for the given images" << std::endl; if (!too_small) { // Mask is too large, loading it would cause a segmentation fault. exit(1); } } importImage(maskInfo, destImage(*mask)); } else { // Cannot read mask file. We already issued an error // message through can_open_file(). exit(1); } return mask; } // Start by using the nearest feature transform to generate a mask. vigra::Size2D mainInputSize, mainInputBBSize; vigra::Rect2D mainInputBB; int mainStride; if (CoarseMask) { // Do MainAlgorithm at 1/CoarsenessFactor scale. // uBB rounded up to multiple of CoarsenessFactor pixels in each direction mainInputSize = vigra::Size2D((uBB.width() + CoarsenessFactor - 1) / CoarsenessFactor, (uBB.height() + CoarsenessFactor - 1) / CoarsenessFactor); mainInputBBSize = vigra::Size2D((iBB.width() + CoarsenessFactor - 1) / CoarsenessFactor, (iBB.height() + CoarsenessFactor - 1) / CoarsenessFactor); mainInputBB = vigra::Rect2D(vigra::Point2D(std::floor(double(iBB.upperLeft().x - uBB.upperLeft().x) / CoarsenessFactor), std::floor(double(iBB.upperLeft().y - uBB.upperLeft().y) / CoarsenessFactor)), mainInputBBSize); mainStride = CoarsenessFactor; } else { // Do MainAlgorithm at 1/1 scale. mainInputSize = uBB.size(); mainInputBB = vigra::Rect2D(iBB); if (mainInputBB.upperLeft().x >= uBB.upperLeft().x) { mainInputBB.moveBy(-uBB.upperLeft()); } else { mainInputBB.moveBy(uBB.upperLeft()); } mainStride = 1; } vigra::Size2D mainOutputSize; vigra::Diff2D mainOutputOffset; // GraphCut supports seam visualization without optimizers if (!CoarseMask && !OptimizeMask && !VisualizeSeam) { // We are not going to vectorize the mask. mainOutputSize = mainInputSize; mainOutputOffset = vigra::Diff2D(0, 0); } else { // Add 1-pixel border all around the image for the vectorization algorithm. mainOutputSize = mainInputSize + vigra::Diff2D(2, 2); mainOutputOffset = vigra::Diff2D(1, 1); } // mem usage before: 0 // mem usage after: CoarseMask: 1/8 * uBB * MaskType // !CoarseMask: uBB * MaskType MaskType* mainOutputImage = new MaskType(mainOutputSize); const unsigned default_norm_value = std::min(static_cast(EuclideanDistance), parameter::as_unsigned("distance-transform-norm", static_cast(EuclideanDistance))); const nearest_neighbor_metric_t norm = static_cast(default_norm_value); if (MainAlgorithm == GraphCut) { graphCut(vigra_ext::stride(mainStride, mainStride, vigra_ext::apply(iBB, srcImageRange(*white))), vigra_ext::stride(mainStride, mainStride, vigra_ext::apply(iBB, srcImage(*black))), vigra::destIter(mainOutputImage->upperLeft() + mainOutputOffset), vigra_ext::stride(mainStride, mainStride, vigra_ext::apply(uBB, srcImageRange(*whiteAlpha))), vigra_ext::stride(mainStride, mainStride, vigra_ext::apply(uBB, srcImage(*blackAlpha))), norm, wraparound ? HorizontalStrip : OpenBoundaries, mainInputBB); } else if (MainAlgorithm == NFT) { nearestFeatureTransform(vigra_ext::stride(mainStride, mainStride, vigra_ext::apply(uBB, srcImageRange(*whiteAlpha))), vigra_ext::stride(mainStride, mainStride, vigra_ext::apply(uBB, srcImage(*blackAlpha))), vigra::destIter(mainOutputImage->upperLeft() + mainOutputOffset), norm, wraparound ? HorizontalStrip : OpenBoundaries); } else { NEVER_REACHED("unexpected value of \"MainAlgorithm\""); } search_for_isolated_points(blackAlpha); #ifdef DEBUG_NEAREST_FEATURE_TRANSFORM { typedef std::pair ImagePair; const std::array nft { std::make_pair("blackmask", blackAlpha), std::make_pair("whitemask", whiteAlpha), std::make_pair("nft-output", mainOutputImage) }; for (const auto& x : nft) { const std::string nftMaskTemplate(command + "-" + x.first + "-%n.tif"); const std::string nftMaskFilename = enblend::expandFilenameTemplate(nftMaskTemplate, numberOfImages, *inputFileNameIterator, OutputFileName, m); if (Verbose >= VERBOSE_NFT_MESSAGES) { std::cerr << command << ": info: saving nearest-feature-transform image \"" << nftMaskFilename << "\"" << std::endl; } vigra::ImageExportInfo nftMaskInfo(nftMaskFilename.c_str()); nftMaskInfo.setCompression(MASK_COMPRESSION); vigra::exportImage(srcImageRange(*x.second), nftMaskInfo); } } #endif // mem usage before: CoarseMask: 2/8 * uBB * MaskType // !CoarseMask: 2 * uBB * MaskType // mem usage after: CoarseMask: 1/8 * uBB * MaskType // !CoarseMask: uBB * MaskType if (!VisualizeSeam && !CoarseMask && !OptimizeMask) { // nftOutputImage is the final mask in this case. return mainOutputImage; } // Vectorize the seam lines found in nftOutputImage. Contour rawSegments; if (MainAlgorithm == GraphCut) { vectorizeSeamLine(rawSegments, whiteAlpha, blackAlpha, uBB, mainStride, mainOutputImage, 4); } else { vectorizeSeamLine(rawSegments, whiteAlpha, blackAlpha, uBB, mainStride, mainOutputImage); } delete mainOutputImage; if (parameter::as_boolean("debug-seam-line", false)) { std::cout << "+ createMask: rawSegments\n"; dump_contour(rawSegments, "+ createMask: "); } // mem usage after: 0 if (!OptimizeMask && !VisualizeSeam) { // Simply fill contours to get final unoptimized mask. MaskType* mask = new MaskType(uBB.size()); fillContour(mask, rawSegments, vigra::Diff2D(0, 0)); // delete all segments in rawSegments std::for_each(rawSegments.begin(), rawSegments.end(), [](Segment* x) {delete x;}); return mask; } ContourVector contours; reorderSnakesToMovableRuns(contours, rawSegments); rawSegments.clear(); if (parameter::as_boolean("debug-seam-line", false)) { std::cout << "+ createMask: contours\n"; dump_contourvector(contours, "+ createMask: "); } { const size_t totalSegments = std::accumulate(contours.begin(), contours.end(), 0U, [](size_t a, const Contour* x) -> size_t {return a + x->size();}); if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << command << ": info: optimizing "; if (totalSegments == 1U) { std::cerr << "1 distinct seam"; } else { std::cerr << totalSegments << " distinct seams"; } std::cerr << std::endl; } if (totalSegments == 0U) { std::cerr << command << ": warning: failed to detect any seam" << std::endl; } } vigra::Rect2D vBB = vertexBoundingBox(contours); vBB.moveBy(uBB.upperLeft()); // move vBB to be root-relative // Make sure that vBB is bigger than iBB by one pixel in each // direction. This will create a max-cost border to keep the seam // line from leaving the intersection region. vigra::Rect2D iBBPlus = iBB; iBBPlus.addBorder(1); vBB |= iBBPlus; // Vertex-Union bounding box: portion of uBB inside vBB const vigra::Rect2D uvBB = vBB & uBB; // Offset between vBB and uvBB const vigra::Diff2D uvBBOffset = uvBB.upperLeft() - vBB.upperLeft(); vigra::Size2D mismatchImageSize; int mismatchImageStride; vigra::Diff2D uvBBStrideOffset; if (CoarseMask) { // Prepare to stride by two over uvBB to create cost image. // Push ul corner of vBB so that there is an even number of // pixels between vBB and uvBB. if (uvBBOffset.x % 2) { vBB.setUpperLeft(vBB.upperLeft() + vigra::Diff2D(-1, 0)); } if (uvBBOffset.y % 2) { vBB.setUpperLeft(vBB.upperLeft() + vigra::Diff2D(0, -1)); } uvBBStrideOffset = (uvBB.upperLeft() - vBB.upperLeft()) / 2; mismatchImageStride = 2; mismatchImageSize = (vBB.size() + vigra::Diff2D(1, 1)) / 2; } else { uvBBStrideOffset = uvBBOffset; mismatchImageStride = 1; mismatchImageSize = vBB.size(); } typedef vigra::UInt8 MismatchImagePixelType; typedef vigra::BasicImage MismatchImageType; typedef vigra::BasicImage > VisualizeImageType; MismatchImageType mismatchImage(mismatchImageSize, vigra::NumericTraits::max()); // Visualization of optimization output VisualizeImageType* visualizeImage = nullptr; if (VisualizeSeam) { visualizeImage = new VisualizeImageType(mismatchImageSize); } // mem usage after: Visualize && CoarseMask: iBB * UInt8 // Visualize && !CoarseMask: 2 * iBB * UInt8 // !Visualize && CoarseMask: 1/2 * iBB * UInt8 // !Visualize && !CoarseMask: iBB * UInt8 // Calculate mismatch image switch (PixelDifferenceFunctor) { case HueLuminanceMaxDifference: vigra::omp::combineTwoImages(vigra_ext::stride(mismatchImageStride, mismatchImageStride, vigra_ext::apply(uvBB, srcImageRange(*white))), vigra_ext::stride(mismatchImageStride, mismatchImageStride, vigra_ext::apply(uvBB, srcImage(*black))), vigra::destIter(mismatchImage.upperLeft() + uvBBStrideOffset), MaxHueLuminanceDifferenceFunctor (LuminanceDifferenceWeight, ChrominanceDifferenceWeight)); break; case DeltaEDifference: vigra::omp::combineTwoImages(vigra_ext::stride(mismatchImageStride, mismatchImageStride, vigra_ext::apply(uvBB, srcImageRange(*white))), vigra_ext::stride(mismatchImageStride, mismatchImageStride, vigra_ext::apply(uvBB, srcImage(*black))), vigra::destIter(mismatchImage.upperLeft() + uvBBStrideOffset), DeltaEPixelDifferenceFunctor (LuminanceDifferenceWeight, ChrominanceDifferenceWeight)); break; default: NEVER_REACHED("switch control expression \"PixelDifferenceFunctor\" out of range"); } if (Verbose >= VERBOSE_DIFFERENCE_STATISTICS) { auto non_maximum(std::bind(std::not_equal_to(), std::placeholders::_1, vigra::NumericTraits::max())); enblend::FindAverageAndVarianceIf statistics(non_maximum); const double range = static_cast(vigra::NumericTraits::max() - vigra::NumericTraits::min()); vigra::inspectImage(srcImageRange(mismatchImage), statistics); std::cerr << command << ": info: difference statistics: overlap size = " << std::count_if(mismatchImage.begin(), mismatchImage.end(), non_maximum) << " pixels\n" << command << ": info: difference statistics: mismatch average = " << statistics.average() / range << " [" << stringOfPixelDifferenceFunctor(PixelDifferenceFunctor) << "]\n" << command << ": info: difference statistics: standard deviation = " << sqrt(statistics.variance()) / range << " [" << stringOfPixelDifferenceFunctor(PixelDifferenceFunctor) << "]" << std::endl; } if (visualizeImage) { // Dump cost image into visualize image. vigra::omp::copyImage(srcImageRange(mismatchImage), destImage(*visualizeImage)); // Color the parts of the visualize image where the two images // to be blended do not overlap. vigra::omp::combineThreeImages(vigra_ext::stride(mismatchImageStride, mismatchImageStride, vigra_ext::apply(uvBB, srcImageRange(*whiteAlpha))), vigra_ext::stride(mismatchImageStride, mismatchImageStride, vigra_ext::apply(uvBB, srcImage(*blackAlpha))), vigra::srcIter(visualizeImage->upperLeft() + uvBBStrideOffset), vigra::destIter(visualizeImage->upperLeft() + uvBBStrideOffset), ifThenElse(Arg1() & Arg2(), Arg3(), Param(VISUALIZE_NO_OVERLAP_VALUE))); const vigra::Diff2D offset = vigra::Diff2D(vBB.upperLeft()) - vigra::Diff2D(uBB.upperLeft()); // Draw the initial seam line as a reference. for (ContourVector::const_iterator v = contours.begin(); v != contours.end(); ++v) { for (Contour::const_iterator c = (*v)->begin(); c != (*v)->end(); ++c) { for (Segment::const_iterator s = (*c)->begin(); s != (*c)->end(); ++s) { Segment::const_iterator next = s; ++next; if (next != (*c)->end()) { visualizeLine(*visualizeImage, (s->second - offset) / mismatchImageStride, (next->second - offset) / mismatchImageStride, VISUALIZE_INITIAL_PATH); } if (OptimizeMask) visualizePoint(*visualizeImage, (s->second - offset) / mismatchImageStride, s->first ? VISUALIZE_MOVABLE_POINT : VISUALIZE_FROZEN_POINT, s->first ? MARK_MOVABLE_POINT : MARK_FROZEN_POINT, 2); } } } } if (OptimizeMask && !parameter::as_boolean("skip-optimizer", false)) { // Move snake points to mismatchImage-relative coordinates if (parameter::as_boolean("adya-snake-points", false)) { for_each_vertex(contours.begin(), contours.end(), [&](Segment::iterator vertex) { vertex->second = (vertex->second + uBB.upperLeft() - vBB.upperLeft()) / mismatchImageStride; }); } else { for_each_vertex(contours.begin(), contours.end(), [&](Segment::iterator vertex) { const vigra::Point2D shifted(vertex->second + uBB.upperLeft() - vBB.upperLeft()); vertex->second = vigra::Point2D(round_to_nearest_div(shifted.px(), mismatchImageStride), round_to_nearest_div(shifted.py(), mismatchImageStride)); }); } std::unique_ptr > params(new std::vector); std::unique_ptr > defaultOptimizerChain(new OptimizerChain (&mismatchImage, visualizeImage, &mismatchImageSize, &mismatchImageStride, &uvBBStrideOffset, &contours, &uBB, &vBB, params.get(), whiteAlpha, blackAlpha, &uvBB)); // Add Strategy 1: Use GDA to optimize placement of snake vertices defaultOptimizerChain->addOptimizer("anneal"); // Add Strategy 2: Use Dijkstra shortest path algorithm between snake vertices defaultOptimizerChain->addOptimizer("dijkstra"); // Fire optimizer chain (runs every optimizer on the list in sequence) if (!parameter::as_boolean("skip-optimizer-chain", false)) { defaultOptimizerChain->runOptimizerChain(); } // Move snake vertices from mismatchImage-relative // coordinates to uBB-relative coordinates. for_each_vertex(contours.begin(), contours.end(), [&](Segment::iterator vertex) {vertex->second = vertex->second * mismatchImageStride + vBB.upperLeft() - uBB.upperLeft();}); } if (visualizeImage) { const std::string visualizeFilename = enblend::expandFilenameTemplate(VisualizeTemplate, numberOfImages, *inputFileNameIterator, OutputFileName, m); if (visualizeFilename == *inputFileNameIterator) { std::cerr << command << ": will not overwrite input image \"" << *inputFileNameIterator << "\" with seam-visualization image" << std::endl; exit(1); } else if (visualizeFilename == OutputFileName) { std::cerr << command << ": will not overwrite output image \"" << OutputFileName << "\" with seam-visualization image" << std::endl; exit(1); } else { if (Verbose >= VERBOSE_MASK_MESSAGES) { std::cerr << command << ": info: saving seam visualization \"" << visualizeFilename << "\"" << std::endl; } vigra::ImageExportInfo visualizeInfo(visualizeFilename.c_str()); visualizeInfo.setCompression(MASK_COMPRESSION); vigra::exportImage(srcImageRange(*visualizeImage), visualizeInfo); } delete visualizeImage; } if (parameter::as_boolean("debug-seam-line", false)) { std::cout << "+ createMask: contours of final optimized mask\n"; dump_contourvector(contours, "+ createMask: "); } // Fill contours to get final optimized mask. MaskType* mask = new MaskType(uBB.size()); std::for_each(contours.begin(), contours.end(), [mask](const Contour* x) {fillContour(mask, *x, vigra::Diff2D(0, 0));}); // Clean up contours std::for_each(contours.begin(), contours.end(), [](const Contour* x) { std::for_each(x->begin(), x->end(), [](Segment* y) {delete y;}); }); std::for_each(contours.begin(), contours.end(), [](const Contour* x) {delete x;}); return mask; } } // namespace enblend #endif // MASK_H_INCLUDED_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/muopt.h0000644000175000017500000001117112641706002013275 00000000000000/* * Copyright (C) 2012-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef MUOPT_H_INCLUDED_ #define MUOPT_H_INCLUDED_ #ifdef HAVE_CONFIG_H #include #endif #define PRAGMA(m_token_sequence) _Pragma(#m_token_sequence) #ifdef __GNUC__ #define PREFETCH(m_addr) __builtin_prefetch(m_addr) #define HINTED_PREFETCH(m_addr, m_rw_hint, m_temporal_locality_hint) \ __builtin_prefetch((m_addr), (m_rw_hint), (m_temporal_locality_hint)) #define EXPECT_RESULT(m_condition, m_expected_result) \ __builtin_expect((m_condition), static_cast(m_expected_result)) #ifdef __ICC // See e.g. // https://software.intel.com/en-us/articles/data-alignment-to-assist-vectorization #define ASSUME_ALIGNED_F_(m_pointer_expression, m_alignment) \ (__assume_aligned(m_pointer_expression, m_alignment), m_pointer_expression) #else #define ASSUME_ALIGNED_F_(m_pointer_expression, m_alignment) \ __builtin_assume_aligned(m_pointer_expression, m_alignment) #endif // __ICC #ifdef DEBUG #define ASSUME_ALIGNED(m_pointer_expression, m_alignment) \ (assert((reinterpret_cast(m_pointer_expression) & ((m_alignment) - 1U)) == size_t()), \ static_cast \ (ASSUME_ALIGNED_F_(m_pointer_expression, m_alignment))) #else #define ASSUME_ALIGNED(m_pointer_expression, m_alignment) \ static_cast \ (ASSUME_ALIGNED_F_(m_pointer_expression, m_alignment)) #endif // DEBUG #ifdef __ICC #define ASSUME_NO_VECTOR_DEPENDENCY PRAGMA(ivdep) #else #define ASSUME_NO_VECTOR_DEPENDENCY PRAGMA(GCC ivdep) #endif // __ICC #ifdef __clang__ #define VECTORIZE_LOOP PRAGMA(clang loop vectorize(enable) interleave(enable)) #define VECTORIZE_LOOP_USING(...) PRAGMA(clang loop __VA_ARGS__) #define NO_VECTORIZE_LOOP PRAGMA(clang loop vectorize(disable) interleave(disable)) #else #define VECTORIZE_LOOP PRAGMA(vector) #define VECTORIZE_LOOP_USING(...) PRAGMA(vector __VA_ARGS__) #define NO_VECTORIZE_LOOP PRAGMA(novector) #endif // __clang__ #if defined(__ICC) #define ASSUME_F_(m_condition) __assume(m_condition) #elif defined(__clang__) // See e.g. // http://clang.llvm.org/docs/LanguageExtensions.html #if __has_builtin(__builtin_assume) #define ASSUME_F_(m_condition) __builtin_assume(m_condition) #else #define ASSUME_F_(m_condition) #endif // __has_builtin #else #define ASSUME_F_(m_condition) #endif #ifdef DEBUG #define ASSUME(m_condition) (assert(m_condition), ASSUME_F_(m_condition)) #else #define ASSUME(m_condition) ASSUME_F_(m_condition) #endif // DEBUG #else // neither GCC family, CLang family, nor ICC #define PREFETCH(m_addr) #define HINTED_PREFETCH(m_addr, m_rw_hint, m_temporal_locality_hint) #define EXPECT_RESULT(m_condition, m_expected_result) (m_condition) #ifdef DEBUG #define ASSUME(m_condition) assert(m_condition) #define ASSUME_ALIGNED(m_pointer_expression, m_alignment) \ (assert((reinterpret_cast(m_pointer_expression) & ((m_alignment) - 1U)) == size_t()), \ (m_pointer_expression)) #else #define ASSUME(m_condition) #define ASSUME_ALIGNED(m_pointer_expression, m_alignment) (m_pointer_expression) #endif // DEBUG #define ASSUME_NO_VECTOR_DEPENDENCY #define VECTORIZE_LOOP #define VECTORIZE_LOOP_USING(...) #define NO_VECTORIZE_LOOP #endif // __GNUC__ typedef enum { PREPARE_FOR_READ, PREPARE_FOR_WRITE } rw_hint; // If data is only touched once, or if the dataset is smaller than the // cache, prefer the non-temporal version; otherwise use one of the // temporal versions. typedef enum { // Fetch data into the first way of the L1/L2 cache, minimizing cache pollution. NO_TEMPORAL_LOCALITY, // Fetch data into the least-recently-used way of the ... LOW_TEMPORAL_LOCALITY, // ... L3 cache? MEDIUM_TEMPORAL_LOCALITY, // ... L2/L3 cache? HIGH_TEMPORAL_LOCALITY // ... L1/L2/L3 cache just as a normal load would do. } temporal_locality_hint; #endif // MUOPT_H_INCLUDED_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/path.h0000644000175000017500000002213412641706002013066 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PATH_H_INCLUDED_ #define PATH_H_INCLUDED_ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include namespace enblend { template class PathCompareFunctor : public std::binary_function { public: explicit PathCompareFunctor(const Image* an_image) : image_(an_image) {} bool operator()(const Point& a_point, const Point& another_point) const { if (parameter::as_boolean("debug-path-compare", false)) { std::cout << "+ PathCompareFunctor::operator(): comparing " << "cost(p1 = " << a_point << ") = " << (*image_)[a_point] << " and " << "cost(p2 = " << another_point << ") = " << (*image_)[another_point] << std::endl; } // want the priority queue sorted in ascending order return (*image_)[a_point] > (*image_)[another_point]; } private: const Image* const image_; }; // class PathCompareFunctor template std::vector* minCostPath(CostImageIterator cost_upperleft, CostImageIterator cost_lowerright, CostAccessor cost_accessor, const vigra::Point2D& startingPoint, const vigra::Point2D& endingPoint) { typedef typename CostAccessor::value_type CostPixelType; typedef typename vigra::NumericTraits::Promote WorkingPixelType; typedef vigra::BasicImage WorkingImageType; typedef std::priority_queue, PathCompareFunctor > PriorityQueue; // 4-bit direction encoding {up, down, left, right} // A 8 9 // 2 0 1 // 6 4 5 // // ANTICIPATED CHANGE: Check whether it is faster to pull out // `neighborArray' and `neighborArrayInverse' as `static // const'. const std::array neighborArray = {0xA, 1, 6, 8, 5, 2, 9, 4}; const std::array neighborArrayInverse = {5, 2, 9, 4, 0xA, 1, 6, 8}; const vigra::Size2D size(cost_lowerright - cost_upperleft); const vigra::Rect2D valid_region(size); vigra::UInt8Image pathNextHop(size); WorkingImageType costSoFar(size, vigra::NumericTraits::max()); // The doubled parentheses in the definition of `pq' avoid "C++'s most-vexing parse", gosh! PriorityQueue pq((PathCompareFunctor(&costSoFar))); std::vector* result = new std::vector; if (parameter::as_boolean("debug-path", false)) { std::cout << "+ minCostPath: size = " << size << "\n" << "+ minCostPath: startingPoint = " << startingPoint << (valid_region.contains(startingPoint) ? "" : " (invalid)") << ", endingPoint = " << endingPoint << (valid_region.contains(endingPoint) ? "" : " (invalid)") << std::endl; } if (valid_region.contains(endingPoint)) { costSoFar[endingPoint] = std::max(vigra::NumericTraits::one(), vigra::NumericTraits::toPromote(cost_accessor(cost_upperleft + endingPoint))); pq.push(endingPoint); } while (!pq.empty()) { vigra::Point2D top = pq.top(); pq.pop(); if (parameter::as_boolean("debug-path", false)) { std::cout << "+ minCostPath: visiting point = " << top << std::endl; } if (top != startingPoint) { WorkingPixelType costToTop = costSoFar[top]; if (parameter::as_boolean("debug-path", false)) { std::cout << "+ minCostPath: costToTop = " << costToTop << std::endl; } // For each 8-neighbor of top with costSoFar == 0 do relax for (int i = 0; i < 8; i++) { // Get the neighbor vigra::UInt8 neighborDirection = neighborArray[i]; vigra::Point2D neighborPoint = top; if (neighborDirection & 0x8) {--neighborPoint.y;} if (neighborDirection & 0x4) {++neighborPoint.y;} if (neighborDirection & 0x2) {--neighborPoint.x;} if (neighborDirection & 0x1) {++neighborPoint.x;} // Make sure neighbor is in valid region if (!valid_region.contains(neighborPoint)) { continue; } if (parameter::as_boolean("debug-path", false)) { std::cout << "+ minCostPath: neighbor = " << neighborPoint << std::endl; } // See if the neighbor has already been visited. // If neighbor has maximal cost, it has not been visited. // If so skip it. WorkingPixelType neighborPreviousCost = costSoFar[neighborPoint]; if (parameter::as_boolean("debug-path", false)) { std::cout << "+ minCostPath: neighborPreviousCost = " << neighborPreviousCost << std::endl; } if (neighborPreviousCost != vigra::NumericTraits::max()) { continue; } WorkingPixelType neighborCost = std::max(vigra::NumericTraits::one(), vigra::NumericTraits::toPromote(cost_accessor(cost_upperleft + neighborPoint))); if (parameter::as_boolean("debug-path", false)) { std::cout << "+ minCostPath: neighborCost = " << neighborCost << std::endl; } if (neighborCost == vigra::NumericTraits::max()) { neighborCost *= 65536; // Can't use << since neighborCost may be floating-point } if ((i & 1) == 0) { // neighbor is diagonal neighborCost = WorkingPixelType(static_cast(neighborCost) * 1.4); } const WorkingPixelType newNeighborCost {vigra::NumericTraits::fromRealPromote(static_cast(neighborCost) + static_cast(costToTop))}; if (newNeighborCost < neighborPreviousCost) { // We have found the shortest path to neighbor. costSoFar[neighborPoint] = newNeighborCost; pathNextHop[neighborPoint] = neighborArrayInverse[i]; pq.push(neighborPoint); } } } else { // If yes then follow back to beginning using pathNextHop // include neither start nor end point in result vigra::UInt8 nextHop = pathNextHop[top]; while (nextHop != 0) { if (nextHop & 0x8) {--top.y;} if (nextHop & 0x4) {++top.y;} if (nextHop & 0x2) {--top.x;} if (nextHop & 0x1) {++top.x;} nextHop = pathNextHop[top]; if (nextHop != 0) { result->push_back(top); } } break; } } return result; } template inline static std::vector* minCostPath(vigra::triple cost, const vigra::Point2D& startingPoint, const vigra::Point2D& endingPoint) { return minCostPath(cost.first, cost.second, cost.third, startingPoint, endingPoint); } } // namespace enblend #endif /* PATH_H_INCLUDED_ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/tiff_message.h0000644000175000017500000000231012641706002014560 00000000000000/* * Copyright (C) 2009-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __TIFF_MESSAGE_H__ #define __TIFF_MESSAGE_H__ #include /** Function that intercepts warnings from the TIFF library */ void tiff_warning(const char* module, const char* format, va_list arguments); /** Function that intercepts errors from the TIFF library */ void tiff_error(const char* module, const char* format, va_list arguments); #endif /* __TIFF_MESSAGE_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/error_message.cc0000644000175000017500000000717112641706002015131 00000000000000/* * Copyright (C) 2009-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #ifdef _WIN32 #include #endif // _WIN32 #ifdef HAVE_CONFIG_H #include #endif #include "error_message.h" namespace enblend { static std::string noErrorMessageAvailable(int anErrorNumber) { std::ostringstream oss; oss << "No detailed error message available; decimal error #" << anErrorNumber; return oss.str(); } std::string errorMessage(int anErrorNumber) { #if !defined(HAVE_STRERROR) && !defined(HAVE_STRERROR_R) return noErrorMessageAvailable(anErrorNumber); #endif #if !defined(HAVE_STRERROR_R) std::string message(strerror(anErrorNumber)); #else const size_t buffer_size = 65536U; std::string message(buffer_size, '\0'); #if defined(STRERROR_R_CHAR_P) char* const message_begin = strerror_r(anErrorNumber, &message[0], buffer_size); if (message_begin != &message[0]) { message = std::string(message_begin); } else { message.resize(message.find('\0')); } #else const int return_code = strerror_r(anErrorNumber, &message[0], buffer_size); if (return_code != 0) { std::ostringstream oss; oss << "Conversion of decimal error #" << anErrorNumber << " to an error message failed with decimal return code " << return_code; return oss.str(); } #endif // STRERROR_R_CHAR_P #endif // HAVE_STRERROR_R #if defined(_WIN32) // strerror translates only errors in C runtime library // now translate errors in Windows API if (message.compare("Unknown error") == 0) { message.clear(); } if (anErrorNumber && message.empty()) { // first check for errors in Windows API LPSTR messageBuffer = nullptr; DWORD size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, anErrorNumber, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); if (size) { // convert codepage to get correct display of all characters, e.g. umlaute LPSTR OEMmessageBuffer = (LPSTR)LocalAlloc(LPTR, (size + 1)*sizeof(char)); if (OEMmessageBuffer) { if (CharToOemBuff(messageBuffer, OEMmessageBuffer, size)) { message = std::string(OEMmessageBuffer, size); } } LocalFree(OEMmessageBuffer); } LocalFree(messageBuffer); } #endif // _WIN32 return message.empty() ? noErrorMessageAvailable(anErrorNumber) : message; } } // namespace enblend enblend-enfuse-4.2/src/numerictraits.h0000644000175000017500000003511712641706002015030 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef NUMERICTRAITS_H_INCLUDED_ #define NUMERICTRAITS_H_INCLUDED_ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "common.h" namespace enblend { struct Error_EnblendNumericTraits_not_specialized_for_this_case {}; template struct EnblendNumericTraits { // Types related to input images typedef Error_EnblendNumericTraits_not_specialized_for_this_case ImagePixelComponentType; typedef Error_EnblendNumericTraits_not_specialized_for_this_case ImagePixelType; typedef Error_EnblendNumericTraits_not_specialized_for_this_case ImageType; typedef Error_EnblendNumericTraits_not_specialized_for_this_case ImageIsScalar; typedef Error_EnblendNumericTraits_not_specialized_for_this_case AlphaPixelType; typedef Error_EnblendNumericTraits_not_specialized_for_this_case AlphaType; // Types related to the mask typedef Error_EnblendNumericTraits_not_specialized_for_this_case MaskPixelType; typedef Error_EnblendNumericTraits_not_specialized_for_this_case MaskType; // Types related to image pyramids typedef Error_EnblendNumericTraits_not_specialized_for_this_case ImagePyramidPixelComponentType; typedef Error_EnblendNumericTraits_not_specialized_for_this_case ImagePyramidPixelType; typedef Error_EnblendNumericTraits_not_specialized_for_this_case ImagePyramidType; enum {ImagePyramidIntegerBits = 0}; enum {ImagePyramidFractionBits = 0}; // Pixel type used by SKIPSM algorithm for intermediate image pixel calculations typedef Error_EnblendNumericTraits_not_specialized_for_this_case SKIPSMImagePixelType; // Pixel type used by SKIPSM algorithm for intermediate alpha pixel calculations typedef Error_EnblendNumericTraits_not_specialized_for_this_case SKIPSMAlphaPixelType; // Types related to mask pyramid typedef Error_EnblendNumericTraits_not_specialized_for_this_case MaskPyramidPixelType; typedef Error_EnblendNumericTraits_not_specialized_for_this_case MaskPyramidType; enum {MaskPyramidIntegerBits = 0}; enum {MaskPyramidFractionBits = 0}; typedef Error_EnblendNumericTraits_not_specialized_for_this_case SKIPSMMaskPixelType; }; #define ENBLEND_NUMERICTRAITS(IMAGE, IMAGECOMPONENT, ALPHA, MASK, \ PYRAMIDCOMPONENT, PYRAMIDINTEGER, PYRAMIDFRACTION, \ SKIPSMIMAGE, SKIPSMALPHA, \ MASKPYRAMID, MASKPYRAMIDINTEGER, MASKPYRAMIDFRACTION, SKIPSMMASK) \ template <> \ struct EnblendNumericTraits \ { \ typedef IMAGECOMPONENT ImagePixelComponentType; \ typedef IMAGECOMPONENT ImagePixelType; \ typedef IMAGE ImageType; \ typedef vigra::VigraTrueType ImageIsScalar; \ typedef ALPHA AlphaPixelType; \ typedef IMAGE AlphaType; \ typedef MASK MaskPixelType; \ typedef IMAGE MaskType; \ typedef PYRAMIDCOMPONENT ImagePyramidPixelComponentType; \ typedef PYRAMIDCOMPONENT ImagePyramidPixelType; \ typedef IMAGE ImagePyramidType; \ enum {ImagePyramidIntegerBits = PYRAMIDINTEGER}; \ enum {ImagePyramidFractionBits = PYRAMIDFRACTION}; \ typedef SKIPSMIMAGE SKIPSMImagePixelComponentType; \ typedef SKIPSMIMAGE SKIPSMImagePixelType; \ static_assert(ImagePyramidIntegerBits >= 0, "ImagePyramidIntegerBits must be non-negative"); \ static_assert(ImagePyramidFractionBits >= 0, "ImagePyramidFractionBits must be non-negative"); \ static_assert(ImagePyramidIntegerBits + ImagePyramidFractionBits + 6 <= 8 * sizeof(SKIPSMImagePixelType) - 1, \ "ImagePyramidIntegerBits + ImagePyramidFractionBits do not fit into SKIPSMImagePixelType"); \ typedef SKIPSMALPHA SKIPSMAlphaPixelType; \ typedef MASKPYRAMID MaskPyramidPixelType; \ typedef IMAGE MaskPyramidType; \ enum {MaskPyramidIntegerBits = MASKPYRAMIDINTEGER}; \ enum {MaskPyramidFractionBits = MASKPYRAMIDFRACTION}; \ typedef SKIPSMMASK SKIPSMMaskPixelType; \ static_assert(MaskPyramidIntegerBits >= 0, "MaskPyramidIntegerBits must be non-negative"); \ static_assert(MaskPyramidFractionBits >= 0, "MaskPyramidFractionBits must be non-negative"); \ static_assert(MaskPyramidIntegerBits + MaskPyramidFractionBits + 6 <= 8 * sizeof(SKIPSMMaskPixelType) - 1, \ "MaskPyramidIntegerBits + MaskPyramidFractionBits do not fit into SKIPSMMaskPixelType"); \ }; \ \ template <> \ struct EnblendNumericTraits > \ { \ typedef IMAGECOMPONENT ImagePixelComponentType; \ typedef vigra::RGBValue ImagePixelType; \ typedef IMAGE > ImageType; \ typedef vigra::VigraFalseType ImageIsScalar; \ typedef ALPHA AlphaPixelType; \ typedef IMAGE AlphaType; \ typedef MASK MaskPixelType; \ typedef IMAGE MaskType; \ typedef PYRAMIDCOMPONENT ImagePyramidPixelComponentType; \ typedef vigra::RGBValue ImagePyramidPixelType; \ typedef IMAGE > ImagePyramidType; \ enum {ImagePyramidIntegerBits = PYRAMIDINTEGER}; \ enum {ImagePyramidFractionBits = PYRAMIDFRACTION}; \ typedef SKIPSMIMAGE SKIPSMImagePixelComponentType; \ typedef vigra::RGBValue SKIPSMImagePixelType; \ typedef SKIPSMALPHA SKIPSMAlphaPixelType; \ typedef MASKPYRAMID MaskPyramidPixelType; \ typedef IMAGE MaskPyramidType; \ enum {MaskPyramidIntegerBits = MASKPYRAMIDINTEGER}; \ enum {MaskPyramidFractionBits = MASKPYRAMIDFRACTION}; \ typedef SKIPSMMASK SKIPSMMaskPixelType; \ } // Traits for converting between image pixel types and pyramid // pixel types Pyramids require one more bit of precision than the // regular image type. // // Notes // * SKIPSM math requires 6 bits on top of the pyramid type. // * The maximum of an N-bit signed integer on a // twos-complement machine is 2^(N - 1) - 1, which is why we // dutifully subtract one of each inequalities' RHS. // * Image Pyramids // (ImagePyramidIntegerBits + 1) + ImagePyramidFractionBits + 6 <= sizeof(SKIPSMImagePixelType) - 1 // (8 + 1) + 7 + 6 = 22 <= 32 - 1 // (16 + 1) + 7 + 6 = 30 <= 32 - 1 // (32 + 1) + 23 + 6 = 62 <= 64 - 1 // 8 + 0 + 6 = 14 # fake value for floating-point scales // * Mask Pyramids // (MaskPyramidIntegerBits + 1) + MaskPyramidFractionBits + 6 <= sizeof(SKIPSMMaskPixelType) - 1 // (8 + 1) + 7 + 6 = 22 <= 32 - 1 // (8 + 1) + 15 + 6 = 30 <= 32 - 1 // // // IMAGE- ALPHA MASK PYRAMID- IMG-PYR. SKIPSM- SKIPSM- MASK- MASK-PYR. SKIPSM- // COMPONENT COMPONENT INT FRAC IMAGE ALPHA PYRAMID INT FRAC MASK // ============== ============= ============= ============= ==== ==== ============= ============= ============= ==== ==== ============ ENBLEND_NUMERICTRAITS(IMAGETYPE, vigra::Int8, vigra::UInt8, vigra::UInt8, vigra::Int16, 9, 7, vigra::Int32, vigra::Int16, vigra::Int16, 9, 7, vigra::Int32); ENBLEND_NUMERICTRAITS(IMAGETYPE, vigra::UInt8, vigra::UInt8, vigra::UInt8, vigra::Int16, 9, 7, vigra::Int32, vigra::Int16, vigra::Int16, 9, 7, vigra::Int32); ENBLEND_NUMERICTRAITS(IMAGETYPE, vigra::Int16, vigra::UInt8, vigra::UInt8, vigra::Int32, 17, 7, vigra::Int32, vigra::Int16, vigra::Int32, 9, 15, vigra::Int32); ENBLEND_NUMERICTRAITS(IMAGETYPE, vigra::UInt16, vigra::UInt8, vigra::UInt8, vigra::Int32, 17, 7, vigra::Int32, vigra::Int16, vigra::Int32, 9, 15, vigra::Int32); #ifdef PREFER_DOUBLE_TO_INT64_AS_SKIPSM_IMAGE_TYPE ENBLEND_NUMERICTRAITS(IMAGETYPE, vigra::Int32, vigra::UInt8, vigra::UInt8, double, 8, 0, double, vigra::Int16, vigra::Int32, 9, 15, vigra::Int32); ENBLEND_NUMERICTRAITS(IMAGETYPE, vigra::UInt32, vigra::UInt8, vigra::UInt8, double, 8, 0, double, vigra::Int16, vigra::Int32, 9, 15, vigra::Int32); #else ENBLEND_NUMERICTRAITS(IMAGETYPE, vigra::Int32, vigra::UInt8, vigra::UInt8, vigra::Int64, 33, 23, vigra::Int64, vigra::Int16, vigra::Int32, 9, 15, vigra::Int32); ENBLEND_NUMERICTRAITS(IMAGETYPE, vigra::UInt32, vigra::UInt8, vigra::UInt8, vigra::Int64, 33, 23, vigra::Int64, vigra::Int16, vigra::Int32, 9, 15, vigra::Int32); #endif ENBLEND_NUMERICTRAITS(IMAGETYPE, vigra::Int64, vigra::UInt8, vigra::UInt8, double, 8, 0, double, vigra::Int16, vigra::Int32, 9, 15, vigra::Int32); ENBLEND_NUMERICTRAITS(IMAGETYPE, vigra::UInt64, vigra::UInt8, vigra::UInt8, double, 8, 0, double, vigra::Int16, vigra::Int32, 9, 15, vigra::Int32); ENBLEND_NUMERICTRAITS(IMAGETYPE, float, vigra::UInt8, vigra::UInt8, double, 8, 0, double, vigra::Int16, vigra::Int32, 9, 15, vigra::Int32); #ifdef PREFER_LONG_DOUBLE_TO_DOUBLE_AS_SKIPSM_IMAGE_TYPE ENBLEND_NUMERICTRAITS(IMAGETYPE, double, vigra::UInt8, vigra::UInt8, long double, 8, 0, long double, vigra::Int16, vigra::Int32, 9, 15, vigra::Int32); #else ENBLEND_NUMERICTRAITS(IMAGETYPE, double, vigra::UInt8, vigra::UInt8, double, 8, 0, double, vigra::Int16, vigra::Int32, 9, 15, vigra::Int32); #endif #undef ENBLEND_NUMERICTRAITS // Traits for correctly handling alpha/mask values in floating point files. // This differs from NumericTraits for floating point values. #define ALPHA_TRAITS(T1, S) \ template <> \ struct AlphaTraits \ { \ static T1 max() \ { \ return S; \ } \ \ static T1 zero() \ { \ return 0; \ } \ }; \ \ template <> \ struct AlphaTraits > \ { \ static T1 max() \ { \ return S; \ } \ \ static T1 zero() \ { \ return 0; \ } \ } template struct AlphaTraits; // Integral: 8 bits ALPHA_TRAITS(unsigned char, std::numeric_limits::max()); ALPHA_TRAITS(signed char, std::numeric_limits::max()); // Integral: 16 bits ALPHA_TRAITS(unsigned short, std::numeric_limits::max()); ALPHA_TRAITS(signed short, std::numeric_limits::max()); // Integral: 32 bits ALPHA_TRAITS(unsigned int, std::numeric_limits::max()); ALPHA_TRAITS(signed int, std::numeric_limits::max()); // Integral: 64 bits ALPHA_TRAITS(unsigned long long int, std::numeric_limits::max()); ALPHA_TRAITS(signed long long int, std::numeric_limits::max()); // Floating Point: 32/64/80 bits ALPHA_TRAITS(float, 1.0); ALPHA_TRAITS(double, 1.0); ALPHA_TRAITS(long double, 1.0); #undef ALPHA_TRAITS } // namespace enblend #endif // NUMERICTRAITS_H_INCLUDED_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/opencl.h0000644000175000017500000006121012663574740013430 00000000000000/* * Copyright (C) 2013-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OPENCL_H_INCLUDED #define OPENCL_H_INCLUDED #ifdef HAVE_CONFIG_H #include #endif #include #include // std::uint8_t #include #include // std::unique_ptr #include #include #include #include // std::runtime_error #include #include #include // std::add_const #include #define __CL_ENABLE_EXCEPTIONS #if defined(HAVE_CL_CL_HPP) #if defined(_WIN32) // CL/cl.hpp does include also windows.h // but we don't want the min/max macros #define NOMINMAX #endif #include #elif defined(HAVE_OPENCL_CL_HPP) #include #endif #ifdef _MSC_VER #define NOINLINE __declspec(noinline) #define UNUSEDVAR #define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n) #if _MSC_VER<1900 #define noexcept throw() #endif #else #define NOINLINE __attribute__((noinline)) #define UNUSEDVAR __attribute__((unused)) #endif #ifndef HAVE_AS_CONST namespace std { // Available in C++17 // See for example: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0007r0.html template inline static const t& as_const(const t& x) noexcept { return x; } template inline static const t #if (defined _MSC_VER) && (_MSC_VER <= 1800) as_const(t&& x) #else as_const(t&& x) noexcept(noexcept(t(x))) #endif { return x; } } #endif namespace cl { // forward declarations class Device; class Event; } namespace ocl { // Answer whether pointer [x] is aligned to a boundary given by // the size of the pointer's target type. template inline static bool is_self_aligned(const t* x) { return reinterpret_cast(x) % sizeof(decltype(x)) == off_t(); } // Answer whether pointer [x] is aligned to an [n]-byte boundary. template inline static bool is_aligned_to(const t* x, size_t n) { return reinterpret_cast(x) % n == off_t(); } template inline static t round_up_to_next_multiple(t a_number, t a_multiple) { if (a_multiple == t()) { return a_number; } else { const t remainder = a_number % a_multiple; if (remainder == t()) { return a_number; } else { return a_number + a_multiple - remainder; } } } template inline static t round_up_to_next_power_of_two(t a_number) { static_assert(std::numeric_limits::is_integer::value, "integral-only template"); assert(a_number >= t()); if (a_number != t() && (a_number & (a_number - 1)) == t()) { return a_number; } else { t result(1); while (result < a_number) { result <<= 1U; } return result; } } std::vector split_string(const std::string& a_string, char a_delimiter, bool keep_empty_tokens = false); std::string consult_file(const std::string& a_filename); class StowFormatFlags { typedef std::stack flag_stack; public: StowFormatFlags(); virtual ~StowFormatFlags(); void push(); void pop(); private: flag_stack cin_flags_; flag_stack cout_flags_; flag_stack cerr_flags_; }; // class StowFormatFlags class ShowProfileData { struct Measurement { Measurement() = delete; Measurement(const std::string& a_label, double a_latency) : label(a_label), latency(a_latency), multi(false) {} std::string label; double latency; bool multi; // summary of multiple events? }; // struct Measurement typedef std::vector result_t; public: ShowProfileData(); virtual ~ShowProfileData(); // With the help of `cl::Device' we can augment the // event-latencies with the timer resolution. If the user // does not set the device we do not print anything related to // the resolution. void set_device(const cl::Device* a_device); void add_result(const std::string& a_label, double a_latency); void add_event_latency(const std::string& a_label, cl::Event& an_event); template void add_event_latencies(const std::string& a_label, input_iterator a_first, input_iterator a_last); void clear_results(); typedef enum {NANO_SECONDS, MICRO_SECONDS, MILLI_SECONDS, SECONDS} base_unit_t; virtual double retrieve_result(const std::string& a_label, base_unit_t a_base_unit = MILLI_SECONDS) const; virtual void show_results(std::ostream& an_output_stream, const std::string& a_prefix = std::string(), base_unit_t a_base_unit = MILLI_SECONDS) const; private: double total_latency() const; const cl::Device* device_; result_t results_; }; // class ShowProfileData #if defined(_OPENCL) || defined(CL_HPP_) #define OPENCL typedef std::vector platform_list_t; typedef std::vector device_list_t; class runtime_error : public std::runtime_error { public: runtime_error() = delete; runtime_error(const std::string& a_message); runtime_error(const cl::Error& an_opencl_error, const std::string& an_additional_message); virtual ~runtime_error() noexcept {} const cl::Error& error() const; const std::string& additional_message() const; private: cl::Error opencl_error_; std::string additional_message_; }; // class runtime_error std::string string_of_error_code(cl_int error_code); std::vector construct_search_path(); void print_opencl_information(bool all_devices = false); void print_gpu_preference(size_t a_preferred_platform_id, size_t a_preferred_device_id); cl::Platform find_platform(/* input/output */ size_t& a_preferred_platform_id); void prefer_device(const cl::Platform& a_platform, size_t a_preferred_platform_id, size_t a_preferred_device_id, /* output */ device_list_t& some_devices); // Create a new context given a_platform and some_devices. This // pointer can be deleted as usual. cl::Context* create_context(const cl::Platform& a_platform, const device_list_t& some_devices); namespace vendor { typedef enum { amd, apple, nvidia, unknown } id_t; } // namespace vendor // Recover the platform vendor's ID from a_context. vendor::id_t derive_vendor_id_from_context(const cl::Context* a_context); double event_latency(cl::Event& an_event); // latency in seconds // Macro CHECK_OPENCL_EVENT is useful to debug out-of-bound // read/write operations of OpenCL kernels. To debug add // invocations of the macro right after each OpenCL // function-call that has a "task-completed event" argument, // m_event being the "task-completed event". // // With CHECK_OPENCL_EVENT out-of-bound reads/writes often // show up as exception cl::Error/"resource exhausted" and // usually the offending kernel is the one to which m_event is // attached. void check_opencl_event(cl::Event& an_event, const char* a_filename, int a_linenumber); #define CHECK_OPENCL_EVENT(m_event) ::ocl::check_opencl_event(m_event, __FILE__, __LINE__) #ifdef DEBUG #define DEBUG_CHECK_OPENCL_EVENT(m_event) CHECK_OPENCL_EVENT(m_event) #else #define DEBUG_CHECK_OPENCL_EVENT(m_event) #endif template void query_device_extensions(const cl::Device& a_device, output_iterator some_extensions) { std::string device_extensions; a_device.getInfo(CL_DEVICE_EXTENSIONS, &device_extensions); std::stringstream extension_stream(device_extensions); std::string extension; while (std::getline(extension_stream, extension, ' ')) { if (!extension.empty()) { *some_extensions++ = extension; } } } //////////////////////////////////////////////////////////////////////////// class ScopedMap { protected: ScopedMap() = delete; ScopedMap(cl::CommandQueue& a_queue, const cl::Buffer& a_buffer, cl_bool is_blocking, cl_map_flags some_flags, ::size_t an_offset, ::size_t a_size, const std::vector* some_prerequisite_events = nullptr, cl::Event* a_target_event = nullptr, cl_int* an_error_code = nullptr) : queue_(a_queue), buffer_(a_buffer), address_(queue_.enqueueMapBuffer(a_buffer, is_blocking, some_flags, an_offset, a_size, some_prerequisite_events, a_target_event, an_error_code)) {} // Anticipated Changes: We can implement the copy-constructor // as well as the assignment operator, but current use cases // do not warrant the effort. ScopedMap(const ScopedMap&) = delete; ScopedMap& operator=(const ScopedMap&) = delete; virtual ~ScopedMap() {queue_.enqueueUnmapMemObject(buffer_, address_);} void* base_address() const {return address_;} private: cl::CommandQueue& queue_; const cl::Buffer& buffer_; void* const address_; }; // class ScopedMap class ScopedReadMap : public ScopedMap { typedef ScopedMap super; public: ScopedReadMap() = delete; ScopedReadMap(cl::CommandQueue& a_queue, const cl::Buffer& a_buffer, cl_bool is_blocking, ::size_t an_offset, ::size_t a_size, const std::vector* some_prerequisite_events = nullptr, cl::Event* a_target_event = nullptr, cl_int* an_error_code = nullptr) : ScopedMap(a_queue, a_buffer, is_blocking, CL_MAP_READ, an_offset, a_size, some_prerequisite_events, a_target_event, an_error_code) {} // See `Anticipated Changes' of super class. ScopedReadMap(const ScopedReadMap&) = delete; ScopedReadMap& operator=(const ScopedReadMap&) = delete; const void* base_address() const {return super::base_address();} template typename std::add_const::type get() const { return std::as_const(static_cast(super::base_address())); } }; // class ScopedReadMap class ScopedWriteMap : public ScopedMap { typedef ScopedMap super; public: ScopedWriteMap() = delete; ScopedWriteMap(cl::CommandQueue& a_queue, const cl::Buffer& a_buffer, cl_bool is_blocking, ::size_t an_offset, ::size_t a_size, const std::vector* some_prerequisite_events = nullptr, cl::Event* a_target_event = nullptr, cl_int* an_error_code = nullptr) : ScopedMap(a_queue, a_buffer, is_blocking, CL_MAP_WRITE, an_offset, a_size, some_prerequisite_events, a_target_event, an_error_code) {} // See `Anticipated Changes' of super class. ScopedWriteMap(const ScopedWriteMap&) = delete; ScopedWriteMap& operator=(const ScopedWriteMap&) = delete; template t get() const { return static_cast(super::base_address()); } }; // class ScopedWriteMap //////////////////////////////////////////////////////////////////////////// class CodePolicy { public: virtual ~CodePolicy() {} }; // class CodePolicy class SourcePolicy : public CodePolicy { public: virtual std::string filename() const = 0; virtual const std::string& text() = 0; std::pair source(); }; // class SourcePolicy class BinaryPolicy : public CodePolicy { public: typedef std::vector code_t; virtual code_t code() = 0; std::pair binary(); }; // class BinaryPolicy class SourceStringPolicy : public SourcePolicy { public: SourceStringPolicy() = delete; explicit SourceStringPolicy(const std::string& a_source_text); std::string filename() const override {return "";} const std::string& text() override; private: std::string text_; }; // class SourceStringPolicy class SourceFilePolicy : public SourcePolicy { public: SourceFilePolicy() = delete; explicit SourceFilePolicy(const std::string& a_source_filename); std::string filename() const override {return filename_;} const std::string& text() override; private: NOINLINE void consult(); std::string filename_; std::string text_; }; // class SourceFilePolicy class BinaryCodePolicy : public BinaryPolicy { public: BinaryCodePolicy() = delete; explicit BinaryCodePolicy(const code_t& a_binary_code); code_t code() override {return code_;} private: code_t code_; }; // class BinaryCodePolicy class BinaryFilePolicy : public BinaryPolicy { public: BinaryFilePolicy() = delete; explicit BinaryFilePolicy(const std::string& a_binary_filename); std::string filename() const {return filename_;} code_t code() override; private: NOINLINE void consult(); std::string filename_; code_t code_; }; // class BinaryFilePolicy //////////////////////////////////////////////////////////////////////////// class BuildableFunction { public: virtual ~BuildableFunction() {} virtual void build(const std::string& a_build_option) = 0; virtual void wait() = 0; }; // class BuildableFunction // Class "Function" is the main helper for constructing // OpenCL-based functionality. // * It supplies access to cl::Context, one or more // * cl::Device objects, as well as one or more associated // cl::CommandQueue objects. // * It frees the developer from caring about the origin // of the source or binary code. // * It assists in getting OpenCL source code compiled. template class Function : public BuildableFunction, public actual_code_policy { public: typedef actual_code_policy code_policy; Function() = delete; Function(const cl::Context& a_context, const std::string& a_string); virtual ~Function() {finalize();} void clear_build_options(); Function& add_build_option(const std::string& an_option); Function& add_build_option(const char* a_format_string, ...); Function& add_extension_macros_to_build_options(const cl::Device& a_device); virtual void build(const std::string& an_extra_build_option = std::string()); virtual void build(const char* a_format_string, ...); std::vector build_logs() const; std::string build_log() const; std::vector binaries() const; BinaryPolicy::code_t binary() const; const cl::Context& context() const; vendor::id_t vendor_id() const; const std::vector& devices() const; const cl::Device& device() const; virtual void wait() {} // Wait for device until source has been compiled. virtual const cl::Program& program(); cl::Kernel create_kernel(const std::string& an_entry_point); std::string build_options(const std::string& an_extra_build_option) const; void add_queue(const cl::Device& a_device); const std::vector& queues() const {return queues_;} cl::CommandQueue& queue(int an_index = 0) {return queues_[an_index];} protected: virtual void update_program_from_source(const cl::Program::Sources& a_source); private: void initialize(); void finalize(); cl::Program program_; cl::Context context_; vendor::id_t vendor_id_; std::vector devices_; std::vector queues_; std::vector build_options_; }; // class Function class FunctionOfString : public Function { typedef Function super; public: typedef SourceStringPolicy source_policy; FunctionOfString() = delete; FunctionOfString(const cl::Context& a_context, const std::string& a_string) : Function(a_context, a_string) {} }; // class FunctionOfString class FunctionOfFile : public Function { typedef Function super; public: typedef SourceFilePolicy source_policy; FunctionOfFile() = delete; FunctionOfFile(const cl::Context& a_context, const std::string& a_source_filename) : Function(a_context, a_source_filename) {} }; // class FunctionOfFile template class LazyFunction : public Function { typedef Function super; public: typedef actual_code_policy code_policy; LazyFunction(const cl::Context& a_context, const std::string& a_string); void build(const std::string& an_extra_build_option = std::string()) override; const cl::Program& program() override { this->wait(); return super::program(); } virtual void notify(cl_program a_program) = 0; protected: // IMPLEMENTATION NOTE: This method could be 'const' in this // class, but derived classes may want to change the instance // (*not* the bool itself, of course), e.g. to lock the access // in a multi-threaded environment. virtual bool build_completed() {return build_completed_;} void set_build_completed(bool has_completed) {build_completed_ = has_completed;} private: static void notify_trampoline(cl_program a_program, void* an_instance); void update_hashes(const std::string& an_extra_build_option); bool needs_building(const std::string& an_extra_build_option); bool build_completed_; size_t text_hash_; size_t build_option_hash_; }; // class LazyFunction template class LazyFunctionCXX : public LazyFunction { typedef LazyFunction super; public: typedef actual_code_policy code_policy; LazyFunctionCXX() = delete; LazyFunctionCXX(const cl::Context& a_context, const std::string& a_string); LazyFunctionCXX(const LazyFunctionCXX&) = delete; LazyFunctionCXX& operator=(const LazyFunctionCXX&) = delete; void wait() override; bool build_completed() override; void notify(cl_program a_program) override; private: std::mutex build_completed_mutex_; std::condition_variable build_completed_condition_; }; // class LazyFunctionCXX class LazyFunctionCXXOfString : public LazyFunctionCXX { public: LazyFunctionCXXOfString() = delete; LazyFunctionCXXOfString(const cl::Context& a_context, const std::string& a_string) : LazyFunctionCXX(a_context, a_string) {} }; // class LazyFunctionCXXOfString class LazyFunctionCXXOfFile : public LazyFunctionCXX { public: LazyFunctionCXXOfFile() = delete; LazyFunctionCXXOfFile(const cl::Context& a_context, const std::string& a_source_filename) : LazyFunctionCXX(a_context, a_source_filename) {} }; // class LazyFunctionCXXOfFile template std::unique_ptr create_function(cl::Context* a_context) { try { return std::unique_ptr(new ocl_function(*a_context)); } catch (ocl::runtime_error& a_runtime_error) { #ifdef DEBUG std::cerr << "+ ocl::create_function: function creation failed with ocl::runtime_error\n" << "+ ocl::create_function: reason: " << a_runtime_error.what() << "\n" << "+ ocl::create_function: message: " << a_runtime_error.additional_message() << "\n"; #endif return std::unique_ptr(nullptr); } catch (cl::Error& an_error) { #ifdef DEBUG std::cerr << "+ ocl::create_function: function creation failed with cl::Error\n" << "+ ocl::create_function: in function " << an_error.what() << "\n" << "+ ocl::create_function: because of " << string_of_error_code(an_error.err()) << "\n"; #endif return std::unique_ptr(nullptr); } } class BatchBuilder { public: virtual void finalize() {} virtual ~BatchBuilder() {} typedef BuildableFunction* value_t; virtual void submit(value_t a_function, const std::string& a_build_option = std::string()) = 0; virtual void submit(value_t a_function, const char *a_format_string, ...); }; // class BatchBuilder // This is the most basic implementation of a BatchBuilder. It // does not perform any parallelization nor does it implement a // sophisticated signal/wait logic. Still, the class may be // valuable // (1) for debugging -- in particular the BatchBuilder // itself or // (2) for systems that cannot reliably implement any of the // more complicated schemes. class SerialBatchBuilder : public BatchBuilder { public: void submit(value_t a_function, const std::string& a_build_option = std::string()); }; // class SerialBatchBuilder class ThreadedBatchBuilder : public BatchBuilder { public: ThreadedBatchBuilder(); ~ThreadedBatchBuilder(); void submit(value_t a_function, const std::string& a_build_option = std::string()); void finalize(); private: static void build_all_trampoline(ThreadedBatchBuilder* self); void build(); void build_all(); struct BuildCommand { BuildCommand() = delete; BuildCommand(value_t a_function, const std::string& a_build_option) : function(a_function), option(a_build_option) {} value_t function; std::string option; }; // class BuildCommand bool run_; std::deque compile_queue_; std::recursive_mutex queue_mutex_; std::condition_variable_any queue_not_empty_; }; // class ThreadedBatchBuilder #else #endif // _OPENCL } // namespace ocl #endif // OPENCL_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/opencl_vigra.h0000644000175000017500000004542312670235356014623 00000000000000/* * Copyright (C) 2015, 2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OPENCL_VIGRA_H_INCLUDED #define OPENCL_VIGRA_H_INCLUDED #ifdef HAVE_CONFIG_H #include #endif #include #include "muopt.h" #include "opencl.h" #include "openmp_vigra.h" namespace vigra { namespace ocl { #ifdef OPENCL #ifndef PREFER_SEPARATE_OPENCL_SOURCE #include "distance_transform_fh.icl" #endif class DistanceTransformFH : public ::ocl::BuildableFunction { public: DistanceTransformFH() = delete; DistanceTransformFH(const cl::Context& a_context) : #ifdef PREFER_SEPARATE_OPENCL_SOURCE f_(a_context, std::string("distance_transform_fh.cl")), #else f_(a_context, distance_transform_fh_source_code), #endif preferred_work_group_size_multiple_(0U), work_group_size_(0U), f_scratch_buffer_(nullptr), d_scratch_buffer_(nullptr), v_scratch_buffer_(nullptr), z_scratch_buffer_(nullptr), write_buffer_prereq_(1U), column_kernel_prereq_(1U), row_kernel_prereq_(1U), read_buffer_prereq_(1U), unmap_buffer_prereq_(1U) { f_.add_build_option("-cl-fast-relaxed-math"); f_.add_build_option("-cl-strict-aliasing"); switch (f_.vendor_id()) { case ::ocl::vendor::amd: // f_.add_build_option("..."); break; case ::ocl::vendor::apple: // f_.add_build_option("..."); break; case ::ocl::vendor::nvidia: f_.add_build_option("-cl-nv-verbose"); break; case ::ocl::vendor::unknown: break; } #ifdef BUILD_EAGERLY build(""); initialize(); #endif } void build(const std::string& a_build_option) { try { std::cerr << "\n+ DistanceTransformFH::build: by request\n\n"; f_.build(a_build_option); std::cerr << "+ DistanceTransformFH::build: log begin ================\n" << f_.build_log() << "\n+ DistanceTransformFH::build: log end ================\n"; } catch (::ocl::runtime_error& an_error) { std::cerr << command << ": " << ::ocl::string_of_error_code(an_error.error().err()) << "\n"; std::vector messages = ::ocl::split_string(an_error.additional_message(), '\n', true); for (auto m : messages) { std::cerr << command << ": note: " << m << "\n"; } exit(1); } } void wait() { f_.wait(); #ifndef BUILD_EAGERLY std::cerr << "\n+ DistanceTransformFH::wait: carry on...\n\n"; initialize(); #endif } template void run(source_iterator a_source_upperleft, source_iterator a_source_lowerright, source_accessor a_source_accessor, destination_iterator a_destination_upperleft, destination_accessor a_destination_accessor, value_type a_background_value, int a_distance_norm) { try { run0(a_source_upperleft, a_source_lowerright, a_source_accessor, a_destination_upperleft, a_destination_accessor, a_background_value, a_distance_norm); return; } catch (cl::Error& a_cl_error) { std::cerr << command << ": warning: falling back from OpenCL to CPU path because of\n" << command << ": warning: plain cl error in function: " << a_cl_error.what() << "\n" << command << ": note: " << ::ocl::string_of_error_code(a_cl_error.err()) << std::endl; } catch (::ocl::runtime_error& an_opencl_runtime_error) { std::cerr << command << ": warning: falling back from OpenCL to CPU path because of\n" << command << ": warning: ocl error in function: " << an_opencl_runtime_error.what() << "\n" << command << ": note: " << ::ocl::string_of_error_code(an_opencl_runtime_error.error().err()) << "\n" << command << ": note: " << an_opencl_runtime_error.additional_message() << std::endl; } vigra::omp::distanceTransform(a_source_upperleft, a_source_lowerright, a_source_accessor, a_destination_upperleft, a_destination_accessor, a_background_value, a_distance_norm); } template void run(vigra::triple a_source, vigra::pair a_destination, value_type a_background, int a_distance_norm) { run(a_source.first, a_source.second, a_source.third, a_destination.first, a_destination.second, a_background, a_distance_norm); } private: template void run0(source_iterator a_source_upperleft, source_iterator a_source_lowerright, source_accessor a_source_accessor, destination_iterator a_destination_upperleft, destination_accessor a_destination_accessor, value_type a_background_value, int a_distance_norm) { wait(); // Ensure that all kernels were built. const vigra::Size2D size(a_source_lowerright - a_source_upperleft); const size_t buffer_size = static_cast(size.area()) * sizeof(float); output_buffer_ = cl::Buffer(f_.context(), CL_MEM_ALLOC_HOST_PTR, buffer_size); float* const buffer_begin = static_cast(f_.queue().enqueueMapBuffer(output_buffer_, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE_INVALIDATE_REGION, 0U, buffer_size, nullptr, &write_buffer_prereq_[0])); vigra::BasicImageView distance_image(buffer_begin, size); vigra::omp::transformImage(a_source_upperleft, a_source_lowerright, a_source_accessor, distance_image.upperLeft(), distance_image.accessor(), vigra::functor::ifThenElse(vigra::functor::Arg1() > vigra::functor::Param(a_background_value), vigra::functor::Param(0.0f), vigra::functor::Param(FLT_MAX))); const cl::NDRange column_global_size(work_group_size(size.width())); const cl::NDRange row_global_size(work_group_size(size.height())); const cl::NDRange local_size(16U); setup(a_distance_norm, size); f_.queue().enqueueWriteBuffer(output_buffer_, CL_FALSE, 0U, buffer_size, buffer_begin, &write_buffer_prereq_, &column_kernel_prereq_[0]); f_.queue().enqueueNDRangeKernel(a_distance_norm >= 2 ? euclidean_column_kernel_ : manhattan_column_kernel_, cl::NullRange, column_global_size, local_size, &column_kernel_prereq_, &row_kernel_prereq_[0]); DEBUG_CHECK_OPENCL_EVENT(row_kernel_prereq_[0]); f_.queue().enqueueNDRangeKernel(a_distance_norm >= 2 ? euclidean_row_kernel_ : manhattan_row_kernel_, cl::NullRange, row_global_size, local_size, &row_kernel_prereq_, &read_buffer_prereq_[0]); DEBUG_CHECK_OPENCL_EVENT(read_buffer_prereq_[0]); f_.queue().enqueueReadBuffer(output_buffer_, CL_TRUE, 0U, buffer_size, buffer_begin, &read_buffer_prereq_, &unmap_buffer_prereq_[0]); vigra::omp::copyImage(distance_image.upperLeft(), distance_image.lowerRight(), distance_image.accessor(), a_destination_upperleft, a_destination_accessor); f_.queue().enqueueUnmapMemObject(output_buffer_, buffer_begin, &unmap_buffer_prereq_, &done_); if (parameter::as_boolean("time-distance-transform", false)) { show_profile_data(size); } teardown(a_distance_norm); } void show_profile_data(const vigra::Size2D& a_size) { if (f_.queue().getInfo() & CL_QUEUE_PROFILING_ENABLE) { ::ocl::ShowProfileData show_profile; show_profile.set_device(&f_.device()); show_profile.add_event_latency("map buffer", write_buffer_prereq_[0]); show_profile.add_event_latency("write buffer", column_kernel_prereq_[0]); show_profile.add_event_latency("column kernel", row_kernel_prereq_[0]); show_profile.add_event_latency("row kernel", read_buffer_prereq_[0]); show_profile.add_event_latency("read buffer", unmap_buffer_prereq_[0]); show_profile.add_event_latency("unmap buffer", done_); const double n = static_cast(a_size.area()); const double delta_t = 1e-3 * f_.device().getInfo(); { const double t_column = show_profile.retrieve_result("column kernel", ::ocl::ShowProfileData::MICRO_SECONDS); const double t_row = show_profile.retrieve_result("row kernel", ::ocl::ShowProfileData::MICRO_SECONDS); std::cerr << "\n" << command << ": timing: OpenCL latencies of `Distance Transform' for\n" << command << ": timing: " << a_size << " = " << n / 1028196.0 << " Mpixel image.\n" << command << ": timing: Column-kernel performance " << n / t_column << "±" << n / t_column * delta_t / t_column << " pixels/µs.\n" << command << ": timing: Row-kernel performance " << n / t_row << "±" << n / t_row * delta_t / t_row << " pixels/µs.\n"; } { const double theta = 2.0 * n * sizeof(float) / 1024.0; const double t = show_profile.retrieve_result("write buffer", ::ocl::ShowProfileData::MICRO_SECONDS) + show_profile.retrieve_result("read buffer", ::ocl::ShowProfileData::MICRO_SECONDS); std::cerr << command << ": timing: Effective bandwidth " << theta / t << "±" << theta / t * delta_t / t << " kB/µs (≙ GB/s).\n"; } show_profile.show_results(std::cerr, command + ": ", ::ocl::ShowProfileData::MICRO_SECONDS); } } void initialize() { if (EXPECT_RESULT(work_group_size_ > 0U, true)) { return; } manhattan_row_kernel_ = f_.create_kernel("manhattan_2d_rows"); manhattan_column_kernel_ = f_.create_kernel("manhattan_2d_columns"); euclidean_row_kernel_ = f_.create_kernel("euclidean_2d_rows"); euclidean_column_kernel_ = f_.create_kernel("euclidean_2d_columns"); cl::Kernel& k = euclidean_row_kernel_; k.getWorkGroupInfo(f_.device(), CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, &preferred_work_group_size_multiple_); size_t device_max_group_size; f_.device().getInfo(CL_DEVICE_MAX_WORK_GROUP_SIZE, &device_max_group_size); size_t kernel_group_size; k.getWorkGroupInfo(f_.device(), CL_KERNEL_WORK_GROUP_SIZE, &kernel_group_size); work_group_size_ = std::min(device_max_group_size, kernel_group_size); } void setup(int a_distance_norm, const vigra::Size2D& a_size) { const size_t max_length = static_cast(std::max(a_size.width(), a_size.height())); const size_t float_size = max_length * max_length * sizeof(cl_float); const size_t int_size = max_length * max_length * sizeof(cl_int); f_scratch_buffer_ = new cl::Buffer(f_.context(), CL_MEM_READ_WRITE, float_size); d_scratch_buffer_ = new cl::Buffer(f_.context(), CL_MEM_READ_WRITE, float_size); cl::Kernel row_kernel; cl::Kernel column_kernel; if (a_distance_norm >= 2) { row_kernel = euclidean_row_kernel_; column_kernel = euclidean_column_kernel_; } else { row_kernel = manhattan_row_kernel_; column_kernel = manhattan_column_kernel_; } row_kernel.setArg(0U, output_buffer_); row_kernel.setArg(1U, static_cast(a_size.width())); row_kernel.setArg(2U, static_cast(a_size.height())); row_kernel.setArg(3U, *f_scratch_buffer_); row_kernel.setArg(4U, *d_scratch_buffer_); column_kernel.setArg(0U, output_buffer_); column_kernel.setArg(1U, static_cast(a_size.width())); column_kernel.setArg(2U, static_cast(a_size.height())); column_kernel.setArg(3U, *f_scratch_buffer_); column_kernel.setArg(4U, *d_scratch_buffer_); if (a_distance_norm >= 2) { v_scratch_buffer_ = new cl::Buffer(f_.context(), CL_MEM_READ_WRITE, int_size); z_scratch_buffer_ = new cl::Buffer(f_.context(), CL_MEM_READ_WRITE, float_size); row_kernel.setArg(5U, *v_scratch_buffer_); row_kernel.setArg(6U, *z_scratch_buffer_); column_kernel.setArg(5U, *v_scratch_buffer_); column_kernel.setArg(6U, *z_scratch_buffer_); } } void teardown(int a_distance_norm __attribute__((unused))) { delete z_scratch_buffer_; delete d_scratch_buffer_; delete v_scratch_buffer_; delete f_scratch_buffer_; } size_t work_group_size(size_t a_suggested_work_group_size) const { return ::ocl::round_up_to_next_multiple(a_suggested_work_group_size, preferred_work_group_size_multiple_); } #ifdef PREFER_SEPARATE_OPENCL_SOURCE ::ocl::LazyFunctionCXXOfFile f_; #else ::ocl::LazyFunctionCXXOfString f_; #endif cl::Kernel manhattan_row_kernel_; cl::Kernel manhattan_column_kernel_; cl::Kernel euclidean_row_kernel_; cl::Kernel euclidean_column_kernel_; size_t preferred_work_group_size_multiple_; size_t work_group_size_; cl::Buffer output_buffer_; cl::Buffer* f_scratch_buffer_; cl::Buffer* d_scratch_buffer_; cl::Buffer* v_scratch_buffer_; cl::Buffer* z_scratch_buffer_; std::vector write_buffer_prereq_; std::vector column_kernel_prereq_; std::vector row_kernel_prereq_; std::vector read_buffer_prereq_; std::vector unmap_buffer_prereq_; cl::Event done_; }; // class DistanceTransformFH #endif // OPENCL } // namespace vigra } // namespace ocl #endif // OPENCL_VIGRA_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/error_message.h0000644000175000017500000000274612641706002014776 00000000000000/* * Copyright (C) 2009-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __ERROR_MESSAGE_H__ #define __ERROR_MESSAGE_H__ #include #if !defined(HAVE_DECL_STRERROR_R) #if defined(STRERROR_R_CHAR_P) // GNU // http://www.gnu.org/software/hello/manual/libc/Error-Messages.html extern char* strerror_r(int errnum, char* buf, size_t buflen); #else // POSIX // http://www.opengroup.org/onlinepubs/9699919799/functions/strerror_r.html extern int strerror_r(int errnum, char* buf, size_t buflen); #endif // STRERROR_R_CHAR_P #endif // !HAVE_DECL_STRERROR_R namespace enblend { /** Answer the error message associated with anErrorNumber. */ std::string errorMessage(int anErrorNumber); } #endif /* __ERROR_MESSAGE_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/opencl_anneal.h0000644000175000017500000004503612670235356014751 00000000000000/* * Copyright (C) 2015, 2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OPENCL_ANNEAL_H_INCLUDED #define OPENCL_ANNEAL_H_INCLUDED #ifdef HAVE_CONFIG_H #include #endif #include "timer.h" #include "opencl.h" namespace ocl { #ifdef OPENCL template inline static void let_host_calculate_state_probabilities(int local_k, floating_point_t * RESTRICT state_probabilities, float * RESTRICT e, float * RESTRICT pi) { for (int j = 0; j < local_k; j++) { const floating_point_t pi_t_j = state_probabilities[j]; pi[j] += pi_t_j; for (int i = j + 1; i < local_k; i++) { const floating_point_t pi_t = state_probabilities[i] + pi_t_j; floating_point_t pi_t_an = pi_t / (static_cast(1) + std::exp(e[j] - e[i])); if (std::isnan(pi_t_an)) { pi_t_an = e[j] > e[i] ? floating_point_t() : pi_t; } pi[j] += pi_t_an; pi[i] += pi_t - pi_t_an; } state_probabilities[j] = pi[j] / static_cast(local_k); } } #ifndef PREFER_SEPARATE_OPENCL_SOURCE #include "calculate_state_probabilities.icl" #endif class CalculateStateProbabilities : public ::ocl::BuildableFunction { enum write_prereq_indexes { E_MAPPED, PI_MAPPED, N_MAPPED_ }; enum kernel_prereq_indexes { E_BUFFER_WRITTEN, PI_BUFFER_WRITTEN, STATE_PROBABILITIES_BUFFER_WRITTEN, N_WRITTEN_ }; enum unmap_prereq_indexes { PI_BUFFER_UPDATED, STATE_PROBABILITIES_BUFFER_UPDATED, N_UPDATED_ }; public: CalculateStateProbabilities() = delete; explicit CalculateStateProbabilities(const cl::Context& a_context) : immediately_fallback_(false), #ifdef PREFER_SEPARATE_OPENCL_SOURCE f_(a_context, std::string("calculate_state_probabilities.cl")), #else f_(a_context, calculate_state_probabilities_source_code), #endif preferred_work_group_size_multiple_(0U), work_group_size_(0U), e_begin_(nullptr), pi_begin_(nullptr), map_complete_(N_MAPPED_), kernel_prereq_(N_WRITTEN_), read_buffer_prereq_(1U), unmap_buffer_prereq_(N_UPDATED_) { query_device_extensions(f_.device(), std::back_inserter(extensions_)); has_extension_fp64_ = !parameter::as_boolean("force-opencl-anneal-float", false) && std::find(extensions_.begin(), extensions_.end(), "cl_khr_fp64") != extensions_.end(); if (has_extension_fp64_) { f_.add_build_option("-DHAVE_EXTENSION_CL_KHR_FP64"); } f_.add_build_option("-cl-fast-relaxed-math"); f_.add_build_option("-cl-unsafe-math-optimizations"); switch (f_.vendor_id()) { case ::ocl::vendor::amd: // f_.add_build_option("..."); break; case ::ocl::vendor::apple: // f_.add_build_option("..."); break; case ::ocl::vendor::nvidia: f_.add_build_option("-cl-nv-verbose"); break; case ::ocl::vendor::unknown: break; } #ifdef BUILD_EAGERLY build(""); initialize(); #endif } void build(const std::string& a_build_option) { try { std::cerr << "\n+ CalculateStateProbabilities::build: by request\n\n"; f_.build(a_build_option); std::cerr << "+ CalculateStateProbabilities::build: log begin ================\n" << f_.build_log() << "\n+ CalculateStateProbabilities::build: log end ================\n"; } catch (ocl::runtime_error& an_error) { std::cerr << command << ": " << ocl::string_of_error_code(an_error.error().err()) << "\n"; std::vector messages = split_string(an_error.additional_message(), '\n', true); for (auto m : messages) { std::cerr << command << ": note: " << m << "\n"; } exit(1); } } void wait() { f_.wait(); #ifndef BUILD_EAGERLY std::cerr << "\n+ CalculateStateProbabilities::wait: carry on...\n\n"; initialize(); #endif } void run(int local_k, std::vector* state_probabilities, int k_max, float* e, float* pi) { if (EXPECT_RESULT(!immediately_fallback_, true)) { try { run0(local_k, state_probabilities, k_max, e, pi); return; } catch (cl::Error& a_cl_error) { std::cerr << command << ": warning: falling back from OpenCL to CPU path because of\n" << command << ": warning: plain cl error in function: " << a_cl_error.what() << "\n" << command << ": note: " << ::ocl::string_of_error_code(a_cl_error.err()) << std::endl; } catch (::ocl::runtime_error& an_opencl_runtime_error) { std::cerr << command << ": warning: falling back from OpenCL to CPU path because of\n" << command << ": warning: ocl error in function: " << an_opencl_runtime_error.what() << "\n" << command << ": note: " << ::ocl::string_of_error_code(an_opencl_runtime_error.error().err()) << "\n" << command << ": note: " << an_opencl_runtime_error.additional_message() << std::endl; } } let_host_calculate_state_probabilities(local_k, &(*state_probabilities)[0], e, pi); } // In setup() the parameter `size' is the maximum number of // elements of any of the `state_probabilities' vectors. void setup(size_t size, size_t k_max, float*& e, float*& pi) { const size_t scratch_size = ::ocl::round_up_to_next_multiple(size, 64UL); const size_t local_k = k_max; state_probabilities_buffer_ = cl::Buffer(f_.context(), CL_MEM_READ_WRITE, size * sizeof(double)); e_buffer_ = cl::Buffer(f_.context(), CL_MEM_ALLOC_HOST_PTR, k_max * sizeof(float)); pi_buffer_ = cl::Buffer(f_.context(), CL_MEM_ALLOC_HOST_PTR, k_max * sizeof(float)); // kernel argument #0, i.e. k_max, will be set in method run(). state_probabilities_kernel_.setArg(1U, state_probabilities_buffer_); state_probabilities_kernel_.setArg(2U, cl::Local(size * sizeof(float))); state_probabilities_kernel_.setArg(3U, e_buffer_); state_probabilities_kernel_.setArg(4U, pi_buffer_); state_probabilities_kernel_.setArg(5U, cl::Local(k_max * sizeof(float))); state_probabilities_kernel_.setArg(6U, static_cast(scratch_size)); state_probabilities_kernel_.setArg(7U, cl::Local(scratch_size * sizeof(float))); e_begin_ = static_cast(f_.queue().enqueueMapBuffer(e_buffer_, CL_FALSE, CL_MEM_READ_ONLY, 0U, local_k * sizeof(float), nullptr, &map_complete_[E_MAPPED])); pi_begin_ = static_cast(f_.queue().enqueueMapBuffer(pi_buffer_, CL_FALSE, CL_MEM_READ_WRITE, 0U, local_k * sizeof(float), nullptr, &map_complete_[PI_MAPPED])); cl::Event::waitForEvents(map_complete_); e = e_begin_; pi = pi_begin_; } void teardown() { f_.queue().enqueueUnmapMemObject(e_buffer_, e_begin_, &unmap_buffer_prereq_); f_.queue().enqueueUnmapMemObject(pi_buffer_, pi_begin_, &unmap_buffer_prereq_); e_begin_ = nullptr; pi_begin_ = nullptr; } private: void write_out_state_probabilities(const std::vector* state_probabilities) { if (has_extension_fp64_) { f_.queue().enqueueWriteBuffer(state_probabilities_buffer_, CL_FALSE, 0U, state_probabilities->size() * sizeof(double), &(*state_probabilities)[0], nullptr, // no prerequisite &kernel_prereq_[STATE_PROBABILITIES_BUFFER_WRITTEN]); } else { const size_t size = state_probabilities->size(); cast_buffer_.resize(size); const double* state_probabilities_begin = ASSUME_ALIGNED(&(*state_probabilities)[0], sizeof(double)); for (size_t i = 0U; i != size; ++i) { cast_buffer_[i] = static_cast(state_probabilities_begin[i]); } f_.queue().enqueueWriteBuffer(state_probabilities_buffer_, CL_FALSE, 0U, size * sizeof(float), &cast_buffer_[0], nullptr, // no prerequisite &kernel_prereq_[STATE_PROBABILITIES_BUFFER_WRITTEN]); } } void read_in_state_probabilities(std::vector* state_probabilities) { if (has_extension_fp64_) { f_.queue().enqueueReadBuffer(state_probabilities_buffer_, CL_FALSE, 0U, state_probabilities->size() * sizeof(double), &(*state_probabilities)[0], &read_buffer_prereq_, &unmap_buffer_prereq_[STATE_PROBABILITIES_BUFFER_UPDATED]); } else { const size_t size = state_probabilities->size(); cast_buffer_.resize(size); double* state_probabilities_begin = ASSUME_ALIGNED(&(*state_probabilities)[0], sizeof(double)); f_.queue().enqueueReadBuffer(state_probabilities_buffer_, CL_FALSE, 0U, size * sizeof(float), &cast_buffer_[0], &read_buffer_prereq_, &unmap_buffer_prereq_[STATE_PROBABILITIES_BUFFER_UPDATED]); for (size_t i = 0U; i != size; ++i) { state_probabilities_begin[i] = static_cast(cast_buffer_[i]); } } } void run0(int local_k, std::vector* state_probabilities, int k_max, float* e, float* pi) { state_probabilities_kernel_.setArg(0U, static_cast(local_k)); write_out_state_probabilities(state_probabilities); f_.queue().enqueueWriteBuffer(e_buffer_, CL_FALSE, 0U, local_k * sizeof(float), e_begin_, &map_complete_, &kernel_prereq_[E_BUFFER_WRITTEN]); f_.queue().enqueueWriteBuffer(pi_buffer_, CL_FALSE, 0U, local_k * sizeof(float), pi_begin_, &map_complete_, &kernel_prereq_[PI_BUFFER_WRITTEN]); f_.queue().enqueueNDRangeKernel(state_probabilities_kernel_, cl::NullRange, cl::NDRange(work_group_size(k_max)), // global size cl::NDRange(work_group_size(k_max)), //cl::NullRange, // local size &kernel_prereq_, &read_buffer_prereq_[0]); DEBUG_CHECK_OPENCL_EVENT(read_buffer_prereq_[0]); read_in_state_probabilities(state_probabilities); f_.queue().enqueueReadBuffer(pi_buffer_, CL_FALSE, 0U, local_k * sizeof(float), pi_begin_, &read_buffer_prereq_, &unmap_buffer_prereq_[PI_BUFFER_UPDATED]); cl::Event::waitForEvents(unmap_buffer_prereq_); if (parameter::as_boolean("profile-state-probabilities", false)) { show_profile_data(state_probabilities->size(), local_k); } } void show_profile_data(size_t size, int local_k) { if (f_.queue().getInfo() & CL_QUEUE_PROFILING_ENABLE) { ShowProfileData show_profile; show_profile.set_device(&f_.device()); show_profile.add_event_latencies("write buffer", kernel_prereq_.begin(), kernel_prereq_.end()); show_profile.add_event_latency("kernel", read_buffer_prereq_[0]); show_profile.add_event_latencies("read buffer", unmap_buffer_prereq_.begin(), unmap_buffer_prereq_.end()); const double delta_t = 1e-3 * f_.device().getInfo(); { const double n = static_cast(local_k * (local_k + 1)); const double t = show_profile.retrieve_result("kernel", ShowProfileData::MICRO_SECONDS); std::cerr << "\n" << command << ": timing: OpenCL latencies of `Calculate State Probabilities' for k = " << local_k << ".\n" << command << ": timing: Kernel performance " << n / t << "±" << n / t * delta_t / t << " probabilities/µs.\n"; } { const double theta = static_cast(2 * size * (has_extension_fp64_ ? sizeof(double) : sizeof(float)) + 3 * local_k * sizeof(float)) / 1024.0; const double t = show_profile.retrieve_result("write buffer", ShowProfileData::MICRO_SECONDS) + show_profile.retrieve_result("read buffer", ShowProfileData::MICRO_SECONDS); std::cerr << command << ": timing: Effective bandwidth " << theta / t << "±" << theta / t * delta_t / t << " kB/µs (≙ GB/s).\n"; } show_profile.show_results(std::cerr, command + ": ", ShowProfileData::MICRO_SECONDS); } } void initialize() { if (EXPECT_RESULT(work_group_size_ > 0U, true)) { return; } state_probabilities_kernel_ = f_.create_kernel("calculate_state_probabilities"); cl::Kernel& k = state_probabilities_kernel_; k.getWorkGroupInfo(f_.device(), CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, &preferred_work_group_size_multiple_); size_t device_max_group_size; f_.device().getInfo(CL_DEVICE_MAX_WORK_GROUP_SIZE, &device_max_group_size); size_t kernel_group_size; k.getWorkGroupInfo(f_.device(), CL_KERNEL_WORK_GROUP_SIZE, &kernel_group_size); work_group_size_ = std::min(device_max_group_size, kernel_group_size); } size_t work_group_size(size_t a_suggested_work_group_size) const { return ::ocl::round_up_to_next_multiple(a_suggested_work_group_size, preferred_work_group_size_multiple_); } bool immediately_fallback_; #ifdef PREFER_SEPARATE_OPENCL_SOURCE ::ocl::LazyFunctionCXXOfFile f_; #else ::ocl::LazyFunctionCXXOfString f_; #endif cl::Kernel state_probabilities_kernel_; std::vector extensions_; size_t preferred_work_group_size_multiple_; size_t work_group_size_; cl::Buffer state_probabilities_buffer_; cl::Buffer e_buffer_; cl::Buffer pi_buffer_; float* e_begin_; float* pi_begin_; std::vector map_complete_; std::vector kernel_prereq_; std::vector read_buffer_prereq_; std::vector unmap_buffer_prereq_; bool has_extension_fp64_; std::vector cast_buffer_; // only used if has_extension_fp64_ == false }; // class CalculateStateProbabilities #endif // OPENCL } // namespace ocl #endif // OPENCL_ANNEAL_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/filenameparse.cc0000644000175000017500000002150612673203067015115 00000000000000/* * Copyright (C) 2009-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Life is tough and then you die. -- Jack Dempsey #include #include #if _WIN32 #include // isalpha #endif #ifdef HAVE_CONFIG_H #include #endif #include "filenameparse.h" #if defined(_MSC_VER) || defined(HAVE_WINDOWS_H) #define PATH_SEPARATOR "\\" #else #define PATH_SEPARATOR "/" #endif #define DOT "." #define DOTDOT ".." #ifdef HAVE_STD_FILESYSTEM #include typedef std::tr2::sys::path basic_path; #endif namespace enblend { bool isRelativePath(const std::string& aFilename) { #if defined HAVE_STD_FILESYSTEM || defined HAVE_BOOST_FILESYSTEM const basic_path path(aFilename); return !path.has_root_directory(); #else const std::string::size_type separator = aFilename.find(PATH_SEPARATOR); #if defined(_MSC_VER) || defined(HAVE_WINDOWS_H) return !(aFilename.size() >= 3 && isalpha(aFilename[0]) && aFilename[1] == ':' && separator == 2); #else return separator != 0; #endif #endif } std::string extractDirname(const std::string& aFilename) { #if defined(HAVE_STD_FILESYSTEM) const basic_path path(aFilename); const std::string directory(path.parent_path().string()); return directory.empty() ? DOT : directory; #else const std::string::size_type separator = aFilename.rfind(PATH_SEPARATOR); return (separator == std::string::npos) ? DOT : aFilename.substr(0, separator); #endif } std::string extractBasename(const std::string& aFilename) { #if defined(HAVE_STD_FILESYSTEM) const basic_path path(aFilename); return path.filename().string(); #else const std::string::size_type separator = aFilename.rfind(PATH_SEPARATOR); return (separator == std::string::npos) ? aFilename : aFilename.substr(separator + 1, aFilename.length() - separator - 1); #endif } std::string extractFilename(const std::string& aFilename) { #if defined(HAVE_STD_FILESYSTEM) const basic_path path(aFilename); return path.stem().string(); #else const std::string::size_type separator = aFilename.rfind(PATH_SEPARATOR); const std::string::size_type dot = aFilename.rfind(DOT); if (separator == std::string::npos) { return (dot == std::string::npos) ? aFilename : aFilename.substr(0, dot); } else { return (dot == std::string::npos) ? aFilename.substr(separator + 1, aFilename.length() - separator - 1) : aFilename.substr(separator + 1, dot - separator - 1); } #endif } std::string extractExtension(const std::string& aFilename) { #if defined(HAVE_STD_FILESYSTEM) const basic_path path(aFilename); return path.extension().string(); #else const std::string::size_type dot = aFilename.rfind(DOT); return (dot == std::string::npos) ? "" : aFilename.substr(dot, aFilename.length() - dot); #endif } typedef std::list list_t; #if defined(HAVE_STD_FILESYSTEM) inline basic_path removeDotsBoost(const basic_path& aPath) { basic_path result; for (basic_path::const_iterator p = aPath.begin(); p != aPath.end(); ++p) { if (*p != DOT) { result /= *p; } } return result; } inline basic_path removeDotDotsBoost(const basic_path& aPath) { list_t directories; for (basic_path::const_iterator p = aPath.begin(); p != aPath.end(); ++p) { if (*p == DOTDOT && !directories.empty() && directories.back() != DOTDOT) { directories.pop_back(); } else { directories.push_back(p->string()); } } basic_path result; for (list_t::const_iterator p = directories.begin(); p != directories.end(); ++p) { result /= *p; } return result; } #else inline std::string removeDotsCxx(const std::string& aPathname) { std::string path(aPathname); std::string::size_type predecessor = std::string::npos; std::string::size_type separator = path.find(PATH_SEPARATOR); while (separator != std::string::npos) { const std::string::size_type begin = predecessor == std::string::npos ? 0 : predecessor + 1; const std::string component = path.substr(begin, separator - predecessor - 1); if (component == DOT) { path.erase(begin, 2); } else { predecessor = separator; } separator = path.find(PATH_SEPARATOR, predecessor + 1); } if (predecessor == std::string::npos) { if (path == DOT) { path.clear(); } } else { const std::string component = path.substr(predecessor + 1); if (component == DOT) { path.erase(predecessor); } } return path; } inline std::string removeDotDotsCxx(const std::string& aPathname) { std::string path(aPathname); list_t directories; std::string::size_type predecessor = std::string::npos; std::string::size_type separator = path.find(PATH_SEPARATOR); while (separator != std::string::npos) { const std::string::size_type begin = predecessor == std::string::npos ? 0 : predecessor + 1; const std::string component = path.substr(begin, separator - predecessor - 1); if (component == DOTDOT && !directories.empty() && directories.back() != DOTDOT) { directories.pop_back(); } else { directories.push_back(component); } predecessor = separator; separator = path.find(PATH_SEPARATOR, predecessor + 1); } if (predecessor == std::string::npos) { directories.push_back(path); } else { const std::string component = path.substr(predecessor + 1); if (component == DOTDOT && !directories.empty() && directories.back() != DOTDOT) { directories.pop_back(); } else { directories.push_back(component); } } std::string result; for (list_t::const_iterator p = directories.begin(); p != directories.end(); ++p) { if (p != directories.begin()) { result.append(PATH_SEPARATOR); } result.append(*p); } return result; } #endif std::string canonicalizePath(const std::string& aPathname, bool keepDot) { #if defined(HAVE_STD_FILESYSTEM) const basic_path result = removeDotDotsBoost(removeDotsBoost(basic_path(aPathname))); if (keepDot && result.empty()) { return std::string(DOT); } else { return result.string(); } #else std::string result = removeDotDotsCxx(removeDotsCxx(aPathname)); // For compatability with the Boost implementation: Remove a // trailing PATH_SEPARATOR unless we reference the root directory. const size_t size = result.size(); if (size >= 2 && result.substr(size - 1, 1) == PATH_SEPARATOR) { result.erase(size - 1, 1); } if (keepDot && result.empty()) { return std::string(DOT); } else { return result; } #endif } std::string concatPath(const std::string& aPathname, const std::string& anotherPathname) { #if defined(HAVE_STD_FILESYSTEM) basic_path path(aPathname); basic_path leaf(anotherPathname); path /= leaf; return path.string(); #else if (aPathname.empty()) { return anotherPathname; } else if (anotherPathname.empty()) { return aPathname; } else { const std::string::size_type end = aPathname.find_last_not_of(PATH_SEPARATOR); const std::string path = (end == std::string::npos) ? aPathname : aPathname.substr(0, end + 1); const std::string::size_type begin = anotherPathname.find_first_not_of(PATH_SEPARATOR); const std::string leaf = (begin == std::string::npos) ? anotherPathname : anotherPathname.substr(begin); return path + PATH_SEPARATOR + leaf; } #endif } } // namespace enblend // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/maskcommon.h0000644000175000017500000002745212641706002014306 00000000000000/* * Copyright (C) 2004-2016 Andrew Mihal, Mikolaj Leszczynski * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef MASKCOMMON_H #define MASKCOMMON_H #include namespace enblend { template class DifferenceFunctor { public: typedef typename EnblendNumericTraits::ImagePixelComponentType PixelComponentType; typedef typename EnblendNumericTraits::ImagePixelComponentType ResultPixelComponentType; typedef vigra::LinearIntensityTransform RangeMapper; DifferenceFunctor() : scale_(vigra::linearRangeMapping(vigra::NumericTraits::min(), vigra::NumericTraits::max(), ResultType(vigra::NumericTraits::min()), ResultType(vigra::NumericTraits::max()))) {} virtual ~DifferenceFunctor() {} ResultType operator()(const PixelType& a, const PixelType& b) const { typedef typename vigra::NumericTraits::isScalar src_is_scalar; return difference(a, b, src_is_scalar()); } protected: virtual ResultType difference(const vigra::RGBValue& a, const vigra::RGBValue& b, vigra::VigraFalseType) const = 0; ResultType difference(PixelType a, PixelType b, vigra::VigraTrueType) const { typedef typename vigra::NumericTraits::isSigned src_is_signed; return scalar_difference(a, b, src_is_signed()); } ResultType scalar_difference(PixelType a, PixelType b, vigra::VigraTrueType) const { return scale_(std::abs(a - b)); } // This appears necessary because NumericTraits::Promote // is an unsigned int instead of an int. ResultType scalar_difference(PixelType a, PixelType b, vigra::VigraFalseType) const { return scale_(std::abs(static_cast(a) - static_cast(b))); } RangeMapper scale_; }; template value_type hue(const vigra::RGBValue& pixel) { typedef typename vigra::NumericTraits::RealPromote real_value_type; const value_type red = pixel.red(); const value_type green = pixel.green(); const value_type blue = pixel.blue(); const value_type max = std::max(red, std::max(green, blue)); const value_type min = std::min(red, std::min(green, blue)); if (min == max) { return vigra::NumericTraits::max(); } else { const real_value_type delta = vigra::NumericTraits::toRealPromote(6 * (max - min)); real_value_type h = 0.0; if (red == max) { h = (green - blue) / delta; } else if (green == max) { h = (1.0 / 3.0) + (blue - red) / delta; } else { h = (2.0 / 3.0) + (red - green) / delta; } if (h < 0.0) { h += 1.0; } return vigra::NumericTraits::fromRealPromote(h * vigra::NumericTraits::max()); } } template class MaxHueLuminanceDifferenceFunctor : public DifferenceFunctor { typedef DifferenceFunctor super; public: typedef typename super::PixelComponentType PixelComponentType; MaxHueLuminanceDifferenceFunctor() = delete; MaxHueLuminanceDifferenceFunctor(double aLuminanceWeight, double aChrominanceWeight) { const double total = aLuminanceWeight + aChrominanceWeight; assert(total != 0.0); luma_ = aLuminanceWeight / total; chroma_ = aChrominanceWeight / total; } protected: ResultType difference(const vigra::RGBValue& a, const vigra::RGBValue& b, vigra::VigraFalseType) const { const PixelComponentType aLum = a.luminance(); const PixelComponentType bLum = b.luminance(); const PixelComponentType aHue = hue(a); const PixelComponentType bHue = hue(b); const PixelComponentType lumDiff = aLum > bLum ? aLum - bLum : bLum - aLum; PixelComponentType hueDiff = aHue > bHue ? aHue - bHue : bHue - aHue; if (hueDiff > (vigra::NumericTraits::max() / 2)) { hueDiff = vigra::NumericTraits::max() - hueDiff; } return super::scale_(std::max(luma_ * lumDiff, chroma_ * hueDiff)); } private: double luma_; double chroma_; }; template class DeltaEPixelDifferenceFunctor : public DifferenceFunctor { typedef DifferenceFunctor super; public: typedef typename super::PixelComponentType PixelComponentType; DeltaEPixelDifferenceFunctor() = delete; DeltaEPixelDifferenceFunctor(double aLuminanceWeight, double aChrominanceWeight) : rgb_to_lab_(vigra::RGB2LabFunctor(vigra::NumericTraits::max())) { const double total = aLuminanceWeight + 2.0 * aChrominanceWeight; assert(total != 0.0); luma_ = aLuminanceWeight / total; chroma_ = aChrominanceWeight / total; } protected: ResultType difference(const vigra::RGBValue& a, const vigra::RGBValue& b, vigra::VigraFalseType) const { typedef typename vigra::RGB2LabFunctor::result_type LABResultType; const LABResultType lab_a = rgb_to_lab_(a); const LABResultType lab_b = rgb_to_lab_(b); // See, e.g. http://en.wikipedia.org/wiki/Color_difference // or http://www.colorwiki.com/wiki/Delta_E:_The_Color_Difference const double delta_e = sqrt(luma_ * square(lab_a[0] - lab_b[0]) + chroma_ * square(lab_a[1] - lab_b[1]) + chroma_ * square(lab_a[2] - lab_b[2])); // Vigra documentation: 0 <= L* <= 100.0, -86.1813 <= a* <= 98.2352, -107.862 <= b* <= 94.4758 // => Maximum delta_e = 291.4619. Real differences are much smaller and fromRealPromote() // clips out-of-destination-range values anyhow. We use 128.0, which yields values comparable // to MaxHueLuminanceDifferenceFunctor. return super::scale_(vigra::NumericTraits:: fromRealPromote(delta_e * vigra::NumericTraits::max() / 128.0)); } private: double luma_; double chroma_; vigra::RGB2LabFunctor rgb_to_lab_; }; template class PixelSumFunctor { typedef typename EnblendNumericTraits::ImagePixelComponentType PixelComponentType; typedef typename EnblendNumericTraits::ImagePixelComponentType ResultPixelComponentType; typedef vigra::LinearIntensityTransform RangeMapper; public: PixelSumFunctor() : rm(linearRangeMapping(vigra::NumericTraits::min(), vigra::NumericTraits::max(), ResultType(vigra::NumericTraits::min()), ResultType(vigra::NumericTraits::max()))) {} ResultType operator()(const PixelType& a, const PixelType& b) const { typedef typename vigra::NumericTraits::isScalar src_is_scalar; return sum(a, b, src_is_scalar()); } protected: ResultType sum(const PixelType& a, const PixelType& b, vigra::VigraFalseType) const { PixelComponentType aLum = a.luminance(); PixelComponentType bLum = b.luminance(); PixelComponentType lumDiff = (aLum + bLum) / 2; return rm(lumDiff); } ResultType sum(const PixelType& a, const PixelType& b, vigra::VigraTrueType) const { typedef typename vigra::NumericTraits::isSigned src_is_signed; return scalar_sum(a, b, src_is_signed()); } ResultType scalar_sum(const PixelType& a, const PixelType& b, vigra::VigraTrueType) const { return rm(a + b); } // This appears necessary because NumericTraits::Promote // is an unsigned int instead of an int. ResultType scalar_sum(const PixelType& a, const PixelType& b, vigra::VigraFalseType) const { return rm(std::abs(static_cast(a) + static_cast(b))); } RangeMapper rm; }; template class MapFunctor { typedef typename EnblendNumericTraits::ImagePixelComponentType PixelComponentType; typedef typename EnblendNumericTraits::ImagePixelComponentType ResultPixelComponentType; typedef vigra::LinearIntensityTransform RangeMapper; public: MapFunctor() : rm(vigra::linearRangeMapping(vigra::NumericTraits::min(), vigra::NumericTraits::max(), ResultType(vigra::NumericTraits::min()), ResultType(vigra::NumericTraits::max()))) {} ResultType operator()(const PixelType& a) const { typedef typename vigra::NumericTraits::isScalar src_is_scalar; return map(a, src_is_scalar()); } protected: ResultType map(const PixelType& a, vigra::VigraFalseType) const { PixelComponentType aLum = a.luminance(); return rm(aLum); } ResultType map(const PixelType& a, vigra::VigraTrueType) const { typedef typename vigra::NumericTraits::isSigned src_is_signed; return scalar_map(a, src_is_signed()); } ResultType scalar_map(const PixelType& a, vigra::VigraTrueType) const { return rm(a); } // This appears necessary because NumericTraits::Promote // is an unsigned int instead of an int. ResultType scalar_map(const PixelType& a, vigra::VigraFalseType) const { return rm(std::abs(static_cast(a))); } RangeMapper rm; }; } // namespace enblend #endif /* MASKCOMMON_H */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/nearest.h0000644000175000017500000004764012662065361013615 00000000000000/* * Copyright (C) 2009-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __NEAREST_H__ #define __NEAREST_H__ #ifdef HAVE_CONFIG_H #include #endif #include #ifdef _WIN32 #include #else #include #endif #include #include #include #include #include #include "timer.h" #include "opencl_vigra.h" #ifdef OPENCL namespace GPU { extern std::unique_ptr DistanceTransform; } #endif namespace vigra { namespace ocl { template inline void distanceTransform(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, ValueType background, int norm) { timer::WallClock wall_clock; wall_clock.start(); #ifdef OPENCL const bool enable_kernel = parameter::as_boolean("gpu-kernel-dt", true); if (GPUContext && GPU::DistanceTransform && enable_kernel) { #ifdef DEBUG std::cerr << command << ": info: choose OpenCL accelaration for Distance Transform" << std::endl; #endif // DEBUG GPU::DistanceTransform->run(src_upperleft, src_lowerright, src_acc, dest_upperleft, dest_acc, background, norm); } else { if (UseGPU && enable_kernel) { std::cerr << command << ": warning: missing GPUContext or OpenCL DistanceTransform\n" << command << ": warning: falling back to CPU path" << std::endl; } vigra::omp::distanceTransform(src_upperleft, src_lowerright, src_acc, dest_upperleft, dest_acc, background, norm); } #else vigra::omp::distanceTransform(src_upperleft, src_lowerright, src_acc, dest_upperleft, dest_acc, background, norm); #endif // OPENCL wall_clock.stop(); if (parameter::as_boolean("time-distance-transform", false)) { const std::ios::fmtflags flags(std::cerr.flags()); vigra::Size2D size(src_lowerright - src_upperleft); std::cerr << "\n" << command << ": timing: wall-clock runtime of `Distance Transform': " << std::setprecision(3) << 1000.0 * wall_clock.value() << " ms\n" << command << ": timing: speed according to wall-clock: " << size.area() / (1048576.0 * wall_clock.value()) << " MPixel/s\n" << std::endl; std::cerr.flags(flags); } } template inline static void distanceTransform(vigra::triple src, vigra::pair dest, ValueType background, int norm) { vigra::ocl::distanceTransform(src.first, src.second, src.third, dest.first, dest.second, background, norm); } } // namespace ocl } // namespace vigra namespace enblend { template void quadruple_image(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, DestImageIterator dest_upperleft, DestAccessor da, boundary_t boundary) { const vigra::Diff2D size_x(src_lowerright.x - src_upperleft.x, 0); const vigra::Diff2D size_y(0, src_lowerright.y - src_upperleft.y); switch (boundary) { case OpenBoundaries: vigra::copyImage(src_upperleft, src_lowerright, sa, dest_upperleft, da); break; case HorizontalStrip: vigra::copyImage(src_upperleft, src_lowerright, sa, dest_upperleft, da); // 11 vigra::copyImage(src_upperleft, src_lowerright, sa, dest_upperleft + size_x, da); // 12 break; case VerticalStrip: vigra::copyImage(src_upperleft, src_lowerright, sa, dest_upperleft, da); // 11 vigra::copyImage(src_upperleft, src_lowerright, sa, dest_upperleft + size_y, da); // 21 break; case DoubleStrip: vigra::copyImage(src_upperleft, src_lowerright, sa, dest_upperleft, da); // 11 vigra::copyImage(src_upperleft, src_lowerright, sa, dest_upperleft + size_x, da); // 12 vigra::copyImage(src_upperleft, src_lowerright, sa, dest_upperleft + size_y, da); // 21 vigra::copyImage(src_upperleft, src_lowerright, sa, dest_upperleft + size_x + size_y, da); // 22 break; default: NEVER_REACHED("switch control expression \"boundary\" out of range"); } } template inline void quadruple_image(vigra::triple src, vigra::pair dest, boundary_t boundary) { quadruple_image(src.first, src.second, src.third, dest.first, dest.second, boundary); } template void quater_image(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, DestImageIterator dest_upperleft, DestAccessor da, boundary_t boundary) { const vigra::Diff2D size_x(src_lowerright.x - src_upperleft.x, 0); const vigra::Diff2D size_y(0, src_lowerright.y - src_upperleft.y); const vigra::Diff2D size_x2(size_x / 2); const vigra::Diff2D size_y2(size_y / 2); const vigra::Diff2D size_x4(size_x2 / 2); const vigra::Diff2D size_y4(size_y2 / 2); // destination image // | 11 12 | // | | // | 21 22 | switch (boundary) { case OpenBoundaries: vigra::copyImage(src_upperleft, src_lowerright, sa, dest_upperleft, da); break; case HorizontalStrip: vigra::copyImage(src_upperleft + size_x2, src_upperleft + size_x2 + size_x4 + size_y, sa, dest_upperleft, da); // 11 vigra::copyImage(src_upperleft + size_x4, src_upperleft + size_x2 + size_y, sa, dest_upperleft + size_x4, da); // 12 break; case VerticalStrip: vigra::copyImage(src_upperleft + size_y2, src_upperleft + size_y2 + size_y4 + size_x, sa, dest_upperleft, da); // 21 vigra::copyImage(src_upperleft + size_y4, src_upperleft + size_y2 + size_x, sa, dest_upperleft + size_y4, da); // 22 break; case DoubleStrip: vigra::copyImage(src_upperleft + size_x2 + size_y2, src_upperleft + size_x2 + size_y2 + size_x4 + size_y4, sa, dest_upperleft, da); // 11 vigra::copyImage(src_upperleft + size_x4 + size_y2, src_upperleft + size_x2 + size_y2 + size_y4, sa, dest_upperleft + size_x4, da); // 12 vigra::copyImage(src_upperleft + size_x2 + size_y4, src_upperleft + size_x2 + size_x4 + size_y2, sa, dest_upperleft + size_y4, da); // 21 vigra::copyImage(src_upperleft + size_x4 + size_y4, src_upperleft + size_x2 + size_y2, sa, dest_upperleft + size_x4 + size_y4, da); // 22 break; default: NEVER_REACHED("switch control expression \"boundary\" out of range"); } } template inline void quater_image(vigra::triple src, vigra::pair dest, boundary_t boundary) { quater_image(src.first, src.second, src.third, dest.first, dest.second, boundary); } template void periodicDistanceTransform(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, DestImageIterator dest_upperleft, DestAccessor da, ValueType background, int norm, boundary_t boundary) { typedef typename SrcImageIterator::value_type SrcValueType; typedef typename DestImageIterator::value_type DestValueType; const vigra::Diff2D size(src_lowerright.x - src_upperleft.x, src_lowerright.y - src_upperleft.y); int size_x; int size_y; switch (boundary) { case OpenBoundaries: size_x = size.x; size_y = size.y; break; case HorizontalStrip: size_x = 2 * size.x; size_y = size.y; break; case VerticalStrip: size_x = size.x; size_y = 2 * size.y; break; case DoubleStrip: size_x = 2 * size.x; size_y = 2 * size.y; break; default: NEVER_REACHED("switch control expression \"boundary\" out of range"); } vigra::BasicImage periodic(size_x, size_y); vigra::BasicImage distance(periodic.size()); quadruple_image(src_upperleft, src_lowerright, sa, periodic.upperLeft(), periodic.accessor(), boundary); vigra::ocl::distanceTransform(srcImageRange(periodic), destImage(distance), background, norm); quater_image(srcImageRange(distance), destIter(dest_upperleft, da), boundary); } template inline void periodicDistanceTransform(vigra::triple src, vigra::pair dest, ValueType background, int norm, boundary_t boundary) { periodicDistanceTransform(src.first, src.second, src.third, dest.first, dest.second, background, norm, boundary); } template struct saturating_subtract { typedef ValueType first_argument_type; typedef ValueType second_argument_type; typedef ValueType result_type; result_type operator()(const first_argument_type& v1, const second_argument_type& v2) const { typedef vigra::NumericTraits traits; return v2 < v1 ? v1 - v2 : traits::zero(); } }; template inline unsigned quick_tally(SrcImageIterator begin, SrcImageIterator end, SrcAccessor acc, unsigned threshold) { typedef typename SrcAccessor::value_type SrcValueType; unsigned count = 0U; SrcImageIterator i = begin; while (count < threshold && i != end) { if (acc(i) != SrcValueType()) { ++count; } ++i; } return count; } template inline unsigned quick_tally(vigra::triple src, unsigned threshold) { return quick_tally(src.first, src.second, src.third, threshold); } // Compute a mask (dest) that defines the seam line given the // blackmask (src1) and the whitemask (src2) of the overlapping // images. // // The idea of the algorithm is from // Yalin Xiong, Ken Turkowski // "Registration, Calibration and Blending in Creating High Quality Panoramas" // Proceedings of the 4th IEEE Workshop on Applications of Computer Vision (WACV'98) // where we find: // "To locate the mask boundary, we perform the grassfire // transform on two images individually. The resulting distance // maps represent how far away each pixel is from its nearest // boundary. The pixel values of the blend mask is then set to // either 0 or 1 by comparing the distance values at each pixel // in the two distance maps." // // Though we prefer the Distance Transform to the Grassfire Transform. template void nearestFeatureTransform(SrcImageIterator src1_upperleft, SrcImageIterator src1_lowerright, SrcAccessor sa1, SrcImageIterator src2_upperleft, SrcAccessor sa2, DestImageIterator dest_upperleft, DestAccessor da, nearest_neighbor_metric_t norm, boundary_t boundary) { typedef typename SrcAccessor::value_type SrcPixelType; typedef vigra::NumericTraits SrcPixelTraits; typedef typename DestAccessor::value_type DestPixelType; typedef vigra::NumericTraits DestPixelTraits; const SrcPixelType background = SrcPixelTraits::zero(); const vigra::Size2D size(src1_lowerright.x - src1_upperleft.x, src1_lowerright.y - src1_upperleft.y); IMAGETYPE dist12(size); IMAGETYPE dist21(size); if (Verbose >= VERBOSE_NFT_MESSAGES) { std::cerr << command << ": info: creating "; if (CoarseMask) { std::cerr << "coarse/" << CoarsenessFactor; } else { std::cerr << "fine"; } std::cerr << " blend mask: 1/3"; std::cerr.flush(); } const unsigned overlap_threshold = // Arbitrary threshold of overlapping pixels below which we // consider the overlap of the masks to be complete, i.e. the // image pair as useless. // // The current parameter default is two times the // circumference of the overlap rectangle. parameter::as_unsigned("overlap-check-threshold", 2U) * //< overlap-check-threshold 2 2U * (static_cast(size.height()) + static_cast(size.width())); IMAGETYPE diff12(size); vigra::omp::combineTwoImages(src1_upperleft, src1_lowerright, sa1, src2_upperleft, sa2, diff12.upperLeft(), diff12.accessor(), saturating_subtract()); const unsigned tally12 = quick_tally(diff12.begin(), diff12.end(), diff12.accessor(), overlap_threshold); switch (boundary) { case OpenBoundaries: vigra::ocl::distanceTransform(srcImageRange(diff12), destImage(dist12), background, norm); break; case HorizontalStrip: // FALLTHROUGH case VerticalStrip: // FALLTHROUGH case DoubleStrip: periodicDistanceTransform(srcImageRange(diff12), destImage(dist12), background, norm, boundary); break; default: NEVER_REACHED("switch control expression \"boundary\" out of range"); } if (Verbose >= VERBOSE_NFT_MESSAGES) { std::cerr << " 2/3"; std::cerr.flush(); } IMAGETYPE diff21(size); vigra::omp::combineTwoImages(src2_upperleft, src2_upperleft + size, sa2, src1_upperleft, sa1, diff21.upperLeft(), diff21.accessor(), saturating_subtract()); const unsigned tally21 = quick_tally(diff21.begin(), diff21.end(), diff21.accessor(), overlap_threshold); switch (boundary) { case OpenBoundaries: vigra::ocl::distanceTransform(srcImageRange(diff21), destImage(dist21), background, norm); break; case HorizontalStrip: // FALLTHROUGH case VerticalStrip: // FALLTHROUGH case DoubleStrip: periodicDistanceTransform(srcImageRange(diff21), destImage(dist21), background, norm, boundary); break; default: NEVER_REACHED("switch control expression \"boundary\" out of range"); } if (Verbose >= VERBOSE_NFT_MESSAGES) { std::cerr << " 3/3"; std::cerr.flush(); } const unsigned overlap_tally = std::max(tally12, tally21); if (overlap_tally < overlap_threshold) { std::cerr << "\n" << command << ": excessive image overlap detected; too high risk of defective seam line\n" << command << ": note: remove at least one of the images" << std::endl; #ifdef DEBUG std::cerr << command << ": note: overlap area size is " << size << " > " << overlap_threshold << ", but only\n" << command << ": note: " << overlap_tally << " of " << size.x * size.y << " pixels do not overlap" << std::endl; #endif exit(1); } vigra::omp::combineTwoImages(dist12.upperLeft(), dist12.lowerRight(), dist12.accessor(), dist21.upperLeft(), dist21.accessor(), dest_upperleft, da, ifThenElse(vigra::functor::Arg1() < vigra::functor::Arg2(), vigra::functor::Param(DestPixelTraits::max()), vigra::functor::Param(DestPixelTraits::zero()))); if (Verbose >= VERBOSE_NFT_MESSAGES) { std::cerr << std::endl; } } template inline void nearestFeatureTransform(vigra::triple src1, vigra::pair src2, vigra::pair dest, nearest_neighbor_metric_t norm, boundary_t boundary) { nearestFeatureTransform(src1.first, src1.second, src1.third, src2.first, src2.second, dest.first, dest.second, norm, boundary); } } // namespace enblend #endif /* __NEAREST_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/enfuse.cc0000644000175000017500000035046312676175540013605 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H #include #endif #ifndef ENFUSE_SOURCE #error trying to compile enfuse.cc without having defined ENFUSE_SOURCE #endif #ifdef ENBLEND_SOURCE #error must not define ENBLEND_SOURCE when compiling enfuse.cc #endif #ifdef _WIN32 // Make sure we bring in windows.h the right way #define _STLP_VERBOSE_AUTO_LINK #define _USE_MATH_DEFINES #define NOMINMAX #define VC_EXTRALEAN #include #undef DIFFERENCE #endif // _WIN32 #ifdef __GW32C__ #undef malloc #define BOOST_NO_STDC_NAMESPACE 1 #endif #include #include #include #include // std::unique_ptr #include #include #include extern "C" char *optarg; extern "C" int optind; #ifndef _MSC_VER #include #endif #include #include #include #include #ifdef _WIN32 #include #endif #include #include // GSL_VERSION #include #if !defined(LCMS_VERSION) || LCMS_VERSION < 2050 #error "Little CMS version 2.5 or later is required" #endif #include "alternativepercentage.h" #include "dynamic_loader.h" #include "exposure_weight.h" #include "global.h" #include "layer_selection.h" #include "parameter.h" #include "selector.h" #include "self_test.h" #include "signature.h" #include "tiff_message.h" #ifdef _MSC_VER #include "win32helpers/delayHelper.h" #endif // Globals const std::string command("enfuse"); // Global values from command line parameters. std::string OutputFileName(DEFAULT_OUTPUT_FILENAME); int Verbose = 1; //< default-verbosity-level 1 int ExactLevels = 0; // 0 means: automatically calculate maximum bool OneAtATime = true; boundary_t WrapAround = OpenBoundaries; bool GimpAssociatedAlphaHack = false; blend_colorspace_t BlendColorspace = UndeterminedColorspace; bool OutputSizeGiven = false; int OutputWidthCmdLine = 0; int OutputHeightCmdLine = 0; int OutputOffsetXCmdLine = 0; int OutputOffsetYCmdLine = 0; std::string OutputCompression; std::string OutputPixelType; double WExposure = 1.0; //< default-weight-exposure 1.0 double ExposureOptimum = 0.5; //< default-exposure-optimum 0.5 double ExposureWidth = 0.2; //< default-exposure-width 0.2 std::string ExposureWeightFunctionName("gaussian"); //< exposure-weight-function gaussian ExposureWeight* ExposureWeightFunction = new exposure_weight::Gaussian(ExposureOptimum, ExposureWidth); ExposureWeight::argument_list_t ExposureWeightFunctionArguments; AlternativePercentage ExposureLowerCutoff(0.0, true); //< default-exposure-lower-cutoff 0% CompactifiedAlternativePercentage ExposureUpperCutoff(100.0, true); //< default-exposure-upper-cutoff 100% std::string ExposureLowerCutoffGrayscaleProjector("anti-value"); //< default-exposure-lower-cutoff-projector anti-value std::string ExposureUpperCutoffGrayscaleProjector("value"); //< default-exposure-upper-cutoff-projector value double WContrast = 0.0; //< default-weight-contrast 0.0 double WSaturation = 0.2; //< default-weight-saturation 0.2 double WEntropy = 0.0; //< default-weight-entropy 0.0 bool WSaturationIsDefault = true; int ContrastWindowSize = 5; //< default-contrast-window-size 5 std::string GrayscaleProjector; struct EdgeFilterConfiguration {double edgeScale, lceScale, lceFactor;} FilterConfig = { 0.0, //< default-edge-scale 0.0 0.0, //< default-lce-scale 0.0 0.0 //< default-lce-factor 0.0 }; AlternativePercentage MinCurvature(0.0, false); //< default-minimum-curvature 0 int EntropyWindowSize = 3; //< default-entropy-window-size 3 AlternativePercentage EntropyLowerCutoff(0.0, true); //< default-entropy-lower-cutoff 0% CompactifiedAlternativePercentage EntropyUpperCutoff(100.0, true); //< default-entropy-upper-cutoff 100% bool UseHardMask = false; bool SaveMasks = false; bool StopAfterMaskGeneration = false; bool LoadMasks = false; std::string SoftMaskTemplate("softmask-%n.tif"); //< default-soft-mask-template softmask-%n.tif std::string HardMaskTemplate("hardmask-%n.tif"); //< default-hard-mask-template hardmask-%n.tif TiffResolution ImageResolution; bool OutputIsValid = true; bool UseGPU = false; namespace cl {class Context;} cl::Context* GPUContext = nullptr; namespace ocl {class BatchBuilder;} ocl::BatchBuilder* BatchCompiler = nullptr; // Globals related to catching SIGINT #ifndef _WIN32 sigset_t SigintMask; #endif // Objects for ICC profiles cmsHPROFILE InputProfile = nullptr; cmsHPROFILE XYZProfile = nullptr; cmsHPROFILE LabProfile = nullptr; cmsHTRANSFORM InputToXYZTransform = nullptr; cmsHTRANSFORM XYZToInputTransform = nullptr; cmsHTRANSFORM InputToLabTransform = nullptr; cmsHTRANSFORM LabToInputTransform = nullptr; cmsViewingConditions ViewingConditions; cmsHANDLE CIECAMTransform = nullptr; cmsHPROFILE FallbackProfile = nullptr; Signature sig; LayerSelectionHost LayerSelection; #include #include #include #include #include "common.h" #include "filespec.h" #include "introspection.h" #include "enfuse.h" #ifdef DMALLOC #include "dmalloc.h" // must be last #include #endif #ifdef _WIN32 #define strdup _strdup #endif // Initialize data structures for precomputed entropy and logarithm. template size_t enblend::Histogram::precomputedSize = 0; template double* enblend::Histogram::precomputedLog = nullptr; template double* enblend::Histogram::precomputedEntropy = nullptr; #define DUMP_GLOBAL_VARIABLES(...) dump_global_variables(__FILE__, __LINE__, ##__VA_ARGS__) void dump_global_variables(const char* file, unsigned line, std::ostream& out = std::cout) { out << "+ " << file << ":" << line << ": state of global variables\n" << "+ Verbose = " << Verbose << ", option \"--verbose\"\n" << "+ OutputFileName = <" << OutputFileName << ">\n" << "+ ExactLevels = " << ExactLevels << "\n" << "+ UseGPU = " << UseGPU << "\n" << "+ OneAtATime = " << enblend::stringOfBool(OneAtATime) << ", option \"-a\"\n" << "+ WrapAround = " << enblend::stringOfWraparound(WrapAround) << ", option \"--wrap\"\n" << "+ GimpAssociatedAlphaHack = " << enblend::stringOfBool(GimpAssociatedAlphaHack) << ", option \"-g\"\n" << "+ BlendColorspace = " << BlendColorspace << ", option \"--blend-colorspace\"\n" << "+ FallbackProfile = " << (FallbackProfile ? enblend::profileDescription(FallbackProfile) : "[none]") << ", option \"--fallback-profile\"\n" << "+ OutputSizeGiven = " << enblend::stringOfBool(OutputSizeGiven) << ", option \"-f\"\n" << "+ OutputWidthCmdLine = " << OutputWidthCmdLine << ", argument to option \"-f\"\n" << "+ OutputHeightCmdLine = " << OutputHeightCmdLine << ", argument to option \"-f\"\n" << "+ OutputOffsetXCmdLine = " << OutputOffsetXCmdLine << ", argument to option \"-f\"\n" << "+ OutputOffsetYCmdLine = " << OutputOffsetYCmdLine << ", argument to option \"-f\"\n" << "+ WExposure = " << WExposure << ", argument to option \"--exposure-weight\"\n" << "+ ExposureOptimum = " << ExposureOptimum << ", argument to option \"--exposure-optimum\"\n" << "+ ExposureWidth = " << ExposureWidth << ", argument to option \"--exposure-width\"\n" << "+ ExposureWeightFunctionName = " << ExposureWeightFunctionName << "\n" << "+ ExposureWeightFunctionArguments = {\n"; for (auto& a : ExposureWeightFunctionArguments) {out << "+ \"" << a << "\"\n";} out << "+ }\n" << "+ ExposureLowerCutoff = {\n" "+ value = " << ExposureLowerCutoff.value() << ",\n" << "+ is_percentage = " << enblend::stringOfBool(ExposureLowerCutoff.is_percentage()) << "\n" << "+ }, first argument to option \"--exposure-cutoff\"\n" << "+ ExposureUpperCutoff = {\n" "+ value = " << ExposureUpperCutoff.value() << ",\n" << "+ is_percentage = " << enblend::stringOfBool(ExposureUpperCutoff.is_percentage()) << "\n" << "+ }, second argument to option \"--exposure-cutoff\"\n" << "+ ExposureLowerCutoffGrayscaleProjector = <" << ExposureLowerCutoffGrayscaleProjector << ">, third argument to option \"--exposure-cutoff\"\n" << "+ ExposureUpperCutoffGrayscaleProjector = <" << ExposureUpperCutoffGrayscaleProjector << ">, fourth argument to option \"--exposure-cutoff\"\n" << "+ WContrast = " << WContrast << ", argument to option \"--contrast-weight\"\n" << "+ WSaturation = " << WSaturation << ", argument to option \"--saturation-weight\"\n" << "+ WEntropy = " << WEntropy << ", argument to option \"--entropy-weight\"\n" << "+ WSaturationIsDefault = " << enblend::stringOfBool(WSaturationIsDefault) << "\n" << "+ ContrastWindowSize = " << ContrastWindowSize << ", argument to option \"--contrast-window-size\"\n" << "+ GrayscaleProjector = <" << GrayscaleProjector << ">, argument to option \"--gray-projector\"\n" << "+ FilterConfig = {\n" << "+ edgeScale = " << FilterConfig.edgeScale << ",\n" << "+ lceScale = " << FilterConfig.lceScale << ",\n" << "+ lceFactor = " << FilterConfig.lceFactor << "\n" << "+ }, arguments to option \"--contrast-edge-scale\"\n" << "+ MinCurvature = {\n" "+ value = " << MinCurvature.value() << ",\n" << "+ is_percentage = " << enblend::stringOfBool(MinCurvature.is_percentage()) << "\n" << "+ }, arguments to option \"--contrast-min-curvature\"\n" << "+ EntropyWindowSize = " << EntropyWindowSize << ", argument to option \"--entropy-window-size\"\n" << "+ EntropyLowerCutoff = {\n" "+ value = " << EntropyLowerCutoff.value() << ",\n" << "+ is_percentage = " << enblend::stringOfBool(EntropyLowerCutoff.is_percentage()) << "\n" << "+ }, first argument to option \"--entropy-cutoff\"\n" << "+ EntropyUpperCutoff = {\n" "+ value = " << EntropyUpperCutoff.value() << ",\n" << "+ is_percentage = " << enblend::stringOfBool(EntropyUpperCutoff.is_percentage()) << "\n" << "+ }, second argument to option \"--entropy-cutoff\"\n" << "+ UseHardMask = " << enblend::stringOfBool(UseHardMask) << ", option \"--hard-mask\" or \"--soft-mask\"\n" << "+ SaveMasks = " << enblend::stringOfBool(SaveMasks) << ", option \"--save-masks\"\n" << "+ SoftMaskTemplate = <" << SoftMaskTemplate << ">, first argument to option \"--save-masks\"\n" << "+ HardMaskTemplate = <" << HardMaskTemplate << ">, second argument to option \"--save-masks\"\n" << "+ OutputCompression = <" << OutputCompression << ">, option \"--compression\"\n" << "+ OutputPixelType = <" << OutputPixelType << ">, option \"--depth\"\n" << "+ end of global variable dump\n"; } void printUsage(const bool error = true) { std::cout << "Usage: enfuse [options] [--output=IMAGE] INPUT...\n" << "Fuse INPUT images into a single IMAGE.\n" << "\n" << "INPUT... are image filenames or response filenames. Response\n" << "filenames start with an \"" << RESPONSE_FILE_PREFIX_CHAR << "\" character.\n" "\n" << "Options:\n" << "Common options:\n" << " -l, --levels=LEVELS limit number of blending LEVELS to use (1 to " << MAX_PYRAMID_LEVELS << ");\n" << " negative number of LEVELS decreases maximum;\n" << " \"auto\" restores the default automatic maximization\n" << " -o, --output=FILE write output to FILE; default: \"" << OutputFileName << "\"\n" << " -v, --verbose[=LEVEL] verbosely report progress; repeat to\n" << " increase verbosity or directly set to LEVEL\n" << " --compression=COMPRESSION\n" << " set compression of output image to COMPRESSION,\n" << " where COMPRESSION is:\n" << " \"deflate\", \"jpeg\", \"lzw\", \"none\", \"packbits\", for TIFF files and\n" << " 0 to 100, or \"jpeg\", \"jpeg-arith\" for JPEG files,\n" << " where \"jpeg\" and \"jpeg-arith\" accept a compression level\n" << #ifdef OPENCL " --gpu employ GPU in addition to CPU for selected computations; negate\n" << " with \"--no-gpu\"\n" << #endif "\n" << "Advanced options:\n" << " --blend-colorspace=COLORSPACE\n" << " force COLORSPACE for blending operations; Enfuse uses\n" << " \"CIELUV\" for images with ICC-profile and \"IDENTITY\" for\n" << " those without and also for all floating-point images;\n" << " other available blend color spaces are \"CIELAB\" and\n" << " \"CIECAM\"\n" << " -c, --ciecam use CIECAM02 to blend colors; disable with \"--no-ciecam\";\n" << " note that this option will be withdrawn in favor of\n" << " \"--blend-colorspace\"\n" << " -d, --depth=DEPTH set the number of bits per channel of the output\n" << " image, where DEPTH is \"8\", \"16\", \"32\", \"r32\", or \"r64\"\n" << " -f WIDTHxHEIGHT[+xXOFFSET+yYOFFSET]\n" << " manually set the size and position of the output\n" << " image; useful for cropped and shifted input\n" << " TIFF images, such as those produced by Nona\n" << " -g associated-alpha hack for Gimp (before version 2)\n" << " and Cinepaint\n" << " -w, --wrap[=MODE] wrap around image boundary, where MODE is \"none\",\n" << " \"horizontal\", \"vertical\", or \"both\"; default: " << enblend::stringOfWraparound(WrapAround) << ";\n" << " without argument the option selects horizontal wrapping\n" << "\n" << "Fusion options:\n" << " --exposure-weight=WEIGHT\n" << " weight given to well-exposed pixels\n" << " (0 <= WEIGHT <= 1); default: " << WExposure << "\n" << " --saturation-weight=WEIGHT\n" << " weight given to highly-saturated pixels\n" << " (0 <= WEIGHT <= 1); default: " << WSaturation << "\n" << " --contrast-weight=WEIGHT\n" << " weight given to pixels in high-contrast neighborhoods\n" << " (0 <= WEIGHT <= 1); default: " << WContrast << "\n" << " --entropy-weight=WEIGHT\n" << " weight given to pixels in high entropy neighborhoods\n" << " (0 <= WEIGHT <= 1); default: " << WEntropy << "\n" << " --exposure-optimum=OPTIMUM\n" << " optimum exposure value, usually the maximum of the weighting\n" << " function (0 <= OPTIMUM <= 1); default: " << ExposureOptimum << "\n" << " --exposure-width=WIDTH\n" << " characteristic width of the weighting function\n" << " (WIDTH > 0); default: " << ExposureWidth << "\n" << " --soft-mask average over all masks; this is the default\n" << " --hard-mask force hard blend masks and no averaging on finest\n" << " scale; this is especially useful for focus\n" << " stacks with thin and high contrast features,\n" << " but leads to increased noise\n" << "\n" << "Expert options:\n" << " --save-masks[=SOFT-TEMPLATE[:HARD-TEMPLATE]]\n" << " save weight masks in SOFT-TEMPLATE and HARD-TEMPLATE;\n" << " conversion chars: \"%i\": mask index, \"%n\": mask number,\n" << " \"%p\": full path, \"%d\": dirname, \"%b\": basename,\n" << " \"%f\": filename, \"%e\": extension; lowercase characters\n" << " refer to input images uppercase to the output image\n" << " default: \"" << SoftMaskTemplate << "\":\"" << HardMaskTemplate << "\"\n" << " --load-masks[=SOFT-TEMPLATE[:HARD-TEMPLATE]]\n" << " skip calculation of weight maps and use the ones\n" << " in the files matching the templates instead. These\n" << " can be either hard or soft masks. For template\n" << " syntax see \"--save-masks\";\n" << " default: \"" << SoftMaskTemplate << "\":\"" << HardMaskTemplate << "\"\n" << " --fallback-profile=PROFILE-FILE\n" << " use the ICC profile from PROFILE-FILE instead of sRGB\n" << " --layer-selector=ALGORITHM\n" << " set the layer selector ALGORITHM;\n" << " default: \"" << LayerSelection.name() << "\"; available algorithms are:\n"; for (selector::algorithm_list::const_iterator i = selector::algorithms.begin(); i != selector::algorithms.end(); ++i) { std::cout << " \"" << (*i)->name() << "\": " << (*i)->description() << "\n"; } std::cout << #ifdef OPENCL " --prefer-gpu=DEVICE select DEVICE on auto-detected platform as GPU\n" << " --prefer-gpu=PLATFORM:DEVICE\n" << " select DEVICE on PLATFORM as GPU\n" << #endif " --parameter=KEY1[=VALUE1][:KEY2[=VALUE2][:...]]\n" << " set one or more KEY-VALUE pairs\n" << "\n" << "Expert fusion options:\n" << " --exposure-weight-function=WEIGHT-FUNCTION" << #ifdef HAVE_DYNAMICLOADER_IMPL " (1st form)" << #endif "\n" << " select one of the built-in exposure WEIGHT-FUNCTIONs:\n" << " \"gaussian\", \"lorentzian\", \"half-sine\", \"full-sine\",\n" << " or \"bi-square\"; default: \"" << ExposureWeightFunctionName << "\"\n" << #ifdef HAVE_DYNAMICLOADER_IMPL " --exposure-weight-function=SHARED-OBJECT:SYMBOL[:ARGUMENT[:...]] (2nd form)\n" << " load user-defined exposure weight function SYMBOL\n" << " from SHARED-OBJECT and optionally pass ARGUMENTs\n" << #endif " --exposure-cutoff=LOWERCUTOFF[:UPPERCUTOFF[:LOWERPROJECTOR[:UPPERPROJECTOR]]]\n" << " LOWERCUTOFF and UPPERCUTOFF are the values below\n" << " or above of which pixels are weighted with zero\n" << " weight in exposure weighting; append \"%\" signs\n" << " for relative values; default: " << ExposureLowerCutoff.str() << ":" << ExposureUpperCutoff.str() << ":" << ExposureLowerCutoffGrayscaleProjector << ":" << ExposureUpperCutoffGrayscaleProjector << "\n" << " --contrast-window-size=SIZE\n" << " set window SIZE for local-contrast analysis\n" << " (SIZE >= 3); default: " << ContrastWindowSize << "\n" << " --contrast-edge-scale=EDGESCALE[:LCESCALE[:LCEFACTOR]]\n" << " set scale on which to look for edges; positive\n" << " LCESCALE switches on local contrast enhancement\n" << " by LCEFACTOR (EDGESCALE, LCESCALE, LCEFACTOR >= 0);\n" << " append \"%\" to LCESCALE for values relative to\n" << " EDGESCALE; append \"%\" to LCEFACTOR for relative\n" << " value; default: " << FilterConfig.edgeScale << ":" << FilterConfig.lceScale << ":" << FilterConfig.lceFactor << "\n" << " --contrast-min-curvature=CURVATURE\n" << " minimum CURVATURE for an edge to qualify; append\n" << " \"%\" for relative values; default: " << MinCurvature.str() << "\n" << " --gray-projector=PROJECTOR\n" << " apply gray-scale PROJECTOR in exposure or contrast\n" << " weighing, where PROJECTOR is one of \"anti-value\",\n" << " \"average\", \"l-star\", \"lightness\", \"luminance\",\n" << " \"pl-star\", \"value\", or\n" << " \"channel-mixer:RED-WEIGHT:GREEN-WEIGHT:BLUE-WEIGHT\";\n" << " default: \"" << enblend::MultiGrayscaleAccessor::Promote>::defaultGrayscaleAccessorName() << "\"\n" << " --entropy-window-size=SIZE\n" << " set window SIZE for local entropy analysis\n" << " (SIZE >= 3); default: " << EntropyWindowSize << "\n" << " --entropy-cutoff=LOWERCUTOFF[:UPPERCUTOFF]\n" << " LOWERCUTOFF is the value below of which pixels are\n" << " treated as black and UPPERCUTOFF is the value above\n" << " of which pixels are treated as white in the entropy\n" << " weighting; append \"%\" signs for relative values;\n" << " default: " << EntropyLowerCutoff.str() << ":" << EntropyUpperCutoff.str() << "\n" << "\n" << "Information options:\n" << " -h, --help print this help message and exit\n" << " -V, --version output version information and exit\n" << " --show-globbing-algorithms\n" << " show all globbing algorithms\n" << #ifdef OPENCL " --show-gpu-info list all available GPUs according to their platform and device;\n" << " inform on current preferences\n" << #endif " --show-image-formats show all recognized image formats and their filename\n" << " extensions\n" << " --show-signature show who compiled the binary when and on which machine\n" << " --show-software-components\n" << " show the software components with which Enfuse was compiled\n" << "\n" << "Enfuse accepts arguments to any option in uppercase as\n" << "well as in lowercase letters.\n" << #if defined(CACHE_IMAGES) || \ defined(OPENMP) || \ (defined(OPENCL) && defined(PREFER_SEPARATE_OPENCL_SOURCE)) "\n" << "Environment:\n" << #endif #ifdef CACHE_IMAGES " TMPDIR The TMPDIR environment variable points to the directory,\n" << " where to store ImageCache files. If unset Enfuse uses \"/tmp\".\n" << #endif #ifdef OPENMP " OMP_NUM_THREADS The OMP_NUM_THREADS environment variable sets the number\n" << " of threads to use in OpenMP parallel regions. If unset\n" << " Enfuse uses as many threads as there are CPUs.\n" << " OMP_DYNAMIC The OMP_DYNAMIC environment variable controls dynamic\n" << " adjustment of the number of threads to use in executing\n" << " OpenMP parallel regions.\n" << #endif #if defined(OPENCL) && defined(PREFER_SEPARATE_OPENCL_SOURCE) " ENBLEND_OPENCL_PATH The ENBLEND_OPENCL_PATH environment variable sets the search\n" << " path for OpenCL source files. Note that the variable name is\n" << " ENBLEND_OPENCL_PATH for Enfuse, too." << #endif "\n" << "Report bugs at <" PACKAGE_BUGREPORT ">." << std::endl; exit(error ? 1 : 0); } void cleanup_output(void) { if (!OutputIsValid) { std::cerr << command << ": info: remove invalid output image \"" << OutputFileName << "\"\n"; errno = 0; if (unlink(OutputFileName.c_str()) != 0) { std::cerr << command << ": warning: could not remove invalid output image \"" << OutputFileName << "\": " << enblend::errorMessage(errno) << "\n"; } } } /** Make sure all cached file images get destroyed, and hence the * temporary files deleted, if we are killed. */ void sigint_handler(int sig) { std::cerr << std::endl << command << ": interrupted" << std::endl; cleanup_output(); #if !defined(__GW32C__) && !defined(_WIN32) struct sigaction action; action.sa_handler = SIG_DFL; action.sa_flags = 0; sigemptyset(&(action.sa_mask)); sigaction(sig, &action, nullptr); #else signal(sig, SIG_DFL); #endif raise(sig); } enum AllPossibleOptions { VersionOption, HelpOption, LevelsOption, OutputOption, VerboseOption, WrapAroundOption /* -w */, CompressionOption, LZWCompressionOption, BlendColorspaceOption, CIECAM02Option, NoCIECAM02Option, FallbackProfileOption, DepthOption, AssociatedAlphaOption /* -g */, GPUOption, NoGPUOption, PreferredGPUOption, SizeAndPositionOption /* -f */, ExposureWeightOption, ExposureCutoffOption, SaturationWeightOption, ContrastWeightOption, EntropyWeightOption, ExposureOptimumOption, ExposureWidthOption, ExposureWeightFunctionOption, SoftMaskOption, HardMaskOption, ContrastWindowSizeOption, GrayProjectorOption, EdgeScaleOption, MinCurvatureOption, EntropyWindowSizeOption, EntropyCutoffOption, DebugOption, SaveMasksOption, LoadMasksOption, LayerSelectorOption, ShowImageFormatsOption, ShowSignatureOption, ShowGlobbingAlgoInfoOption, ShowSoftwareComponentsInfoOption, ShowGPUInfoOption, }; typedef std::set OptionSetType; bool contains(const OptionSetType& optionSet, enum AllPossibleOptions anOption) { return optionSet.count(anOption) != 0; } /** Warn if options given at the command line have no effect. */ void warn_of_ineffective_options(const OptionSetType& optionSet) { if (contains(optionSet, LoadMasksOption)) { if (contains(optionSet, ExposureWeightOption)) { std::cerr << command << ": warning: option \"--exposure-weight\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, ExposureCutoffOption)) { std::cerr << command << ": warning: option \"--exposure-cutoff\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, SaturationWeightOption)) { std::cerr << command << ": warning: option \"--saturation-weight\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, ContrastWeightOption)) { std::cerr << command << ": warning: option \"--contrast-weight\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, EntropyWeightOption)) { std::cerr << command << ": warning: option \"--entropy-weight\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, ExposureOptimumOption)) { std::cerr << command << ": warning: option \"--exposure-optimum\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, ExposureWidthOption)) { std::cerr << command << ": warning: option \"--exposure-width\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, ContrastWindowSizeOption)) { std::cerr << command << ": warning: option \"--contrast-window-size\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, GrayProjectorOption)) { std::cerr << command << ": warning: option \"--gray-projector\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, EdgeScaleOption)) { std::cerr << command << ": warning: option \"--contrast-edge-scale\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, MinCurvatureOption)) { std::cerr << command << ": warning: option \"--contrast-min-curvature\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, EntropyWindowSizeOption)) { std::cerr << command << ": warning: option \"--entropy-window-size\" has no effect with \"--load-masks\"" << std::endl; } if (contains(optionSet, EntropyCutoffOption)) { std::cerr << command << ": warning: option \"--entropy-cutoff\" has no effect with \"--load-masks\"" << std::endl; } } if (contains(optionSet, SaveMasksOption) && !contains(optionSet, OutputOption)) { if (contains(optionSet, LevelsOption)) { std::cerr << command << ": warning: option \"--levels\" has no effect with \"--save-masks\" and no \"--output\"" << std::endl; } if (contains(optionSet, WrapAroundOption)) { std::cerr << command << ": warning: option \"--wrap\" has no effect with \"--save-masks\" and no \"--output\"" << std::endl; } if (contains(optionSet, CompressionOption)) { std::cerr << command << ": warning: option \"--compression\" has no effect with \"--save-masks\" and no \"--output\"" << std::endl; } if (contains(optionSet, DepthOption)) { std::cerr << command << ": warning: option \"--depth\" has no effect with \"--save-masks\" and no \"--output\"" << std::endl; } if (contains(optionSet, SizeAndPositionOption)) { std::cerr << command << ": warning: option \"-f\" has no effect with \"--save-masks\" and no \"--output\"" << std::endl; } } if (WExposure == 0.0 && contains(optionSet, ExposureWeightOption)) { if (contains(optionSet, ExposureOptimumOption)) { std::cerr << command << ": warning: option \"--exposure-optimum\" has no effect as exposure weight\n" << command << ": warning: is zero" << std::endl; } if (contains(optionSet, ExposureWidthOption)) { std::cerr << command << ": warning: option \"--exposure-width\" has no effect as exposure weight\n" << command << ": warning: is zero" << std::endl; } } if (WExposure == 0.0 && contains(optionSet, ExposureCutoffOption)) { std::cerr << command << ": warning: option \"--exposure-cutoff\" has no effect as exposure weight\n" << command << ": warning: is zero" << std::endl; } if (WContrast == 0.0 && contains(optionSet, ContrastWindowSizeOption)) { std::cerr << command << ": warning: option \"--contrast-window-size\" has no effect as contrast\n" << command << ": warning: weight is zero" << std::endl; } if (WExposure == 0.0 && WContrast == 0.0 && contains(optionSet, GrayProjectorOption)) { std::cerr << command << ": warning: option \"--gray-projector\" has no effect as exposure\n" << command << ": warning: and contrast weight both are zero" << std::endl; } if (WContrast == 0.0) { if (contains(optionSet, EdgeScaleOption)) { std::cerr << command << ": warning: option \"--contrast-edge-scale\" has no effect as contrast\n" << command << ": warning: weight is zero" << std::endl; } if (contains(optionSet, MinCurvatureOption)) { std::cerr << command << ": warning: option \"--contrast-min-curvature\" has no effect as contrast\n" << command << ": warning: weight is zero" << std::endl; } } else { if (FilterConfig.edgeScale > 0.0 && contains(optionSet, ContrastWindowSizeOption) && MinCurvature.value() <= 0.0) { std::cerr << command << ": warning: option \"--contrast-window-size\" has no effect as\n" << command << ": warning: EDGESCALE in \"--contrast-edge-scale\" is positive and" << command << ": warning: \"--contrast-min-curvature\" is non-positive" << std::endl; } } if (WEntropy == 0.0) { if (contains(optionSet, EntropyWindowSizeOption)) { std::cerr << command << ": warning: option \"--entropy-window-size\" has no effect as\n" << command << ": warning: entropy weight is zero" << std::endl; } if (contains(optionSet, EntropyCutoffOption)) { std::cerr << command << ": warning: option \"--entropy-cutoff\" has no effect as entropy\n" << command << ": warning: weight is zero" << std::endl; } } if (contains(optionSet, CompressionOption) && !(enblend::getFileType(OutputFileName) == "TIFF" || enblend::getFileType(OutputFileName) == "JPEG")) { std::cerr << command << ": warning: compression is not supported with output\n" << command << ": warning: file type \"" << enblend::getFileType(OutputFileName) << "\"" << std::endl; } if (contains(optionSet, AssociatedAlphaOption) && enblend::getFileType(OutputFileName) != "TIFF") { std::cerr << command << ": warning: option \"-g\" has no effect with output\n" << command << ": warning: file type \"" << enblend::getFileType(OutputFileName) << "\"" << std::endl; } #ifdef OPENCL if (!UseGPU && contains(optionSet, PreferredGPUOption)) { std::cerr << command << ": warning: option \"--preferred-gpu\" has no effect without enabled GPU" << std::endl; } #else if (contains(optionSet, GPUOption)) { std::cerr << command << ": warning: option \"--gpu\" has no effect in this " << command << " binary,\n" << command << ": warning: because " << command << " was compiled without support for OpenCL" << std::endl; } if (contains(optionSet, NoGPUOption)) { std::cerr << command << ": warning: option \"--no-gpu\" has no effect in this " << command << " binary,\n" << command << ": warning: because " << command << " was compiled without support for OpenCL" << std::endl; } if (contains(optionSet, PreferredGPUOption)) { std::cerr << command << ": warning: option \"--prefer-gpu\" has no effect in this " << command << " binary,\n" << command << ": warning: because " << command << " was compiled without support for OpenCL" << std::endl; } #endif // OPENCL } void fill_mask_templates(const char* an_option_argument, std::string& a_soft_mask_template, std::string& a_hard_mask_template, const std::string& an_option_name) { if (an_option_argument != nullptr && *an_option_argument != 0) { boost::char_separator separator(PATH_OPTION_DELIMITERS, "", boost::keep_empty_tokens); const std::string arg(an_option_argument); boost::tokenizer > tokenizer(arg, separator); boost::tokenizer >::iterator token = tokenizer.begin(); a_soft_mask_template = *token; ++token; if (token != tokenizer.end()) { a_hard_mask_template = *token; } ++token; if (token != tokenizer.end()) { std::cerr << command << ": warning: ignoring trailing garbage in \"" << an_option_name << "\"" << std::endl; } } } const struct option* lookup_long_option_by_id(struct option* an_option_array, int a_long_option_id) { assert(an_option_array != nullptr); struct option* opt = an_option_array; while (opt->name != 0) { if (opt->val == a_long_option_id) { return opt; } ++opt; } return nullptr; } bool short_option_requires_argument(const char* a_short_option_spec, char a_short_option) { if (a_short_option != 0) { const char* c = strchr(a_short_option_spec, a_short_option); if (c != nullptr) { if (*(c + 1) == ':' && *(c + 2) != ':') { return true; } } } return false; } #ifdef OPENCL void initialize_gpu_subsystem(size_t a_preferred_gpu_platform, size_t a_preferred_gpu_device) { static bool is_initialized = false; if (is_initialized) { return; } try { cl::Platform platform = ocl::find_platform(a_preferred_gpu_platform); ocl::device_list_t devices; ocl::prefer_device(platform, a_preferred_gpu_platform, a_preferred_gpu_device, devices); GPUContext = ocl::create_context(platform, devices); if (Verbose >= VERBOSE_OPENCL_MESSAGES) { std::cerr << command << ": info: chose OpenCL platform #" << a_preferred_gpu_platform << ", "; std::string info; platform.getInfo(CL_PLATFORM_VENDOR, &info); std::cerr << info << ", "; platform.getInfo(CL_PLATFORM_NAME, &info); std::cerr << info << ", device #" << a_preferred_gpu_device << std::endl; } #ifdef OPENMP BatchCompiler = new ocl::ThreadedBatchBuilder; #else BatchCompiler = new ocl::SerialBatchBuilder; #endif is_initialized = true; } catch (ocl::runtime_error& an_exception) { std::cerr << command << ": warning: " << an_exception.what() << ";\n" << command << ": warning: " << " cannot enable GPU" << std::endl; } if (!gpu_is_ok(GPUContext)) { std::cerr << command << ": warning: at least one of Enfuse's GPU tests has failed\n" << command << ": note: refusing to activate GPU support" << std::endl; delete GPUContext; delete BatchCompiler; GPUContext = nullptr; BatchCompiler = nullptr; } } #endif // OPENCL int process_options(int argc, char** argv) { enum OptionId { OPTION_ID_OFFSET = 1023, // Ids start at 1024 UseGpuId, NoUseGpuId, PreferGpuId, CompressionId, WeightExposureId, WeightContrastId, WeightSaturationId, ExposureOptimumId, ObsoleteExposureOptimumId, ExposureWidthId, ObsoleteExposureWidthId, ExposureWeightFunctionId, MinCurvatureId, EdgeScaleId, ContrastWindowSizeId, HardMaskId, GrayProjectorId, WeightEntropyId, EntropyWindowSizeId, EntropyCutoffId, SoftMaskId, VerboseId, HelpId, VersionId, DepthId, OutputId, SaveMasksId, WrapAroundId, LevelsId, BlendColorspaceId, CiecamId, NoCiecamId, FallbackProfileId, ExposureCutoffId, LoadMasksId, LayerSelectorId, ParameterId, NoParameterId, ImageFormatsInfoId, SignatureInfoId, GlobbingAlgoInfoId, SoftwareComponentsInfoId, GPUInfoId }; static struct option long_options[] = { {"gpu", no_argument, 0, UseGpuId}, {"no-gpu", no_argument, 0, NoUseGpuId}, {"prefer-gpu", required_argument, 0, PreferGpuId}, {"preferred-gpu", required_argument, 0, PreferGpuId}, // gramatically close alternative form {"compression", required_argument, 0, CompressionId}, {"exposure-weight", required_argument, 0, WeightExposureId}, {"contrast-weight", required_argument, 0, WeightContrastId}, {"saturation-weight", required_argument, 0, WeightSaturationId}, {"exposure-mu", required_argument, 0, ObsoleteExposureOptimumId}, {"exposure-optimum", required_argument, 0, ExposureOptimumId}, {"exposure-sigma", required_argument, 0, ObsoleteExposureWidthId}, {"exposure-width", required_argument, 0, ExposureWidthId}, {"exposure-weight-function", required_argument, 0, ExposureWeightFunctionId}, {"contrast-min-curvature", required_argument, 0, MinCurvatureId}, {"contrast-edge-scale", required_argument, 0, EdgeScaleId}, {"contrast-window-size", required_argument, 0, ContrastWindowSizeId}, {"hard-mask", no_argument, 0, HardMaskId}, {"gray-projector", required_argument, 0, GrayProjectorId}, {"entropy-weight", required_argument, 0, WeightEntropyId}, {"entropy-window-size", required_argument, 0, EntropyWindowSizeId}, {"entropy-cutoff", required_argument, 0, EntropyCutoffId}, {"soft-mask", no_argument, 0, SoftMaskId}, {"verbose", optional_argument, 0, VerboseId}, {"help", no_argument, 0, HelpId}, {"version", no_argument, 0, VersionId}, {"depth", required_argument, 0, DepthId}, {"output", required_argument, 0, OutputId}, {"save-mask", optional_argument, 0, SaveMasksId}, // singular form: not documented, not deprecated {"save-masks", optional_argument, 0, SaveMasksId}, {"wrap", optional_argument, 0, WrapAroundId}, {"blend-colorspace", required_argument, 0, BlendColorspaceId}, {"blend-color-space", required_argument, 0, BlendColorspaceId}, // dash form: not documented, not deprecated {"levels", required_argument, 0, LevelsId}, {"ciecam", no_argument, 0, CiecamId}, {"no-ciecam", no_argument, 0, NoCiecamId}, {"fallback-profile", required_argument, 0, FallbackProfileId}, {"exposure-cutoff", required_argument, 0, ExposureCutoffId}, {"load-mask", optional_argument, 0, LoadMasksId}, // singular form: not documented, not deprecated {"load-masks", optional_argument, 0, LoadMasksId}, {"layer-selector", required_argument, 0, LayerSelectorId}, {"parameter", required_argument, 0, ParameterId}, {"no-parameter", required_argument, 0, NoParameterId}, {"show-image-formats", no_argument, 0, ImageFormatsInfoId}, {"show-signature", no_argument, 0, SignatureInfoId}, {"show-globbing-algorithms", no_argument, 0, GlobbingAlgoInfoId}, {"show-software-components", no_argument, 0, SoftwareComponentsInfoId}, {"show-gpu-info", no_argument, 0, GPUInfoId}, {0, 0, 0, 0} }; bool failed = false; typedef enum { PROCESS_COMPLETELY, VERSION_ONLY, USAGE_ONLY, IMAGE_FORMATS_ONLY, SIGNATURE_ONLY, GLOBBING_ALGOS_ONLY, SOFTWARE_COMPONENTS_ONLY, GPU_INFO_COMPONENTS_ONLY } print_only_task_id_t; print_only_task_id_t print_only_task = PROCESS_COMPLETELY; OptionSetType optionSet; #ifdef OPENCL size_t preferredGPUPlatform = 0U; // We start enumerating platforms at 1 for user convenience. // Zero means we choose the first platform found, i.e. auto-detect. size_t preferredGPUDevice = 1U; // We start enumerating platforms at 1 for user convenience. #endif static const char short_options[] = "Vb:cd:f:ghl:m:o:v::w::"; opterr = 0; // we have our own "unrecognized option" message while (true) { int option_index = -1; const int code = getopt_long(argc, argv, short_options, long_options, &option_index); if (code == -1) { break; } switch (code) { case UseGpuId: UseGPU = true; optionSet.insert(GPUOption); break; case NoUseGpuId: UseGPU = false; optionSet.insert(NoGPUOption); break; case PreferGpuId: #ifdef OPENCL { char* delimiter = strpbrk(optarg, NUMERIC_OPTION_DELIMITERS); if (delimiter == nullptr) { preferredGPUDevice = enblend::numberOfString(optarg, [](unsigned x) {return x >= 1U;}, "preferred GPU device out of range", 1U); } else { *delimiter = 0; ++delimiter; preferredGPUPlatform = enblend::numberOfString(optarg, [](unsigned x) {return x >= 1U;}, "preferred GPU platform out of range", 1U); preferredGPUDevice = enblend::numberOfString(delimiter, [](unsigned x) {return x >= 1U;}, "preferred GPU device out of range", 1U); } } #endif optionSet.insert(PreferredGPUOption); break; case HardMaskId: UseHardMask = true; optionSet.insert(HardMaskOption); break; case SoftMaskId: UseHardMask = false; optionSet.insert(SoftMaskOption); break; case 'h': BOOST_FALLTHROUGH; case HelpId: print_only_task = USAGE_ONLY; optionSet.insert(HelpOption); break; case 'V': BOOST_FALLTHROUGH; case VersionId: print_only_task = VERSION_ONLY; optionSet.insert(VersionOption); break; case ImageFormatsInfoId: print_only_task = IMAGE_FORMATS_ONLY; optionSet.insert(ShowImageFormatsOption); break; case SignatureInfoId: print_only_task = SIGNATURE_ONLY; optionSet.insert(ShowSignatureOption); break; case GlobbingAlgoInfoId: print_only_task = GLOBBING_ALGOS_ONLY; optionSet.insert(ShowGlobbingAlgoInfoOption); break; case SoftwareComponentsInfoId: print_only_task = SOFTWARE_COMPONENTS_ONLY; optionSet.insert(ShowSoftwareComponentsInfoOption); break; case GPUInfoId: print_only_task = GPU_INFO_COMPONENTS_ONLY; optionSet.insert(ShowGPUInfoOption); break; case 'w': BOOST_FALLTHROUGH; case WrapAroundId: if (optarg != nullptr && *optarg != 0) { WrapAround = enblend::wraparoundOfString(optarg); if (WrapAround == UnknownWrapAround) { std::cerr << command << ": unrecognized wrap-around mode \"" << optarg << "\"\n" << std::endl; failed = true; } } else { WrapAround = HorizontalStrip; } optionSet.insert(WrapAroundOption); break; case MinCurvatureId: { char *tail; errno = 0; MinCurvature.set_value(strtod(optarg, &tail)); if (errno == 0) { if (*tail == 0) { MinCurvature.set_percentage(false); } else if (strcmp(tail, "%") == 0) { MinCurvature.set_percentage(true); } else { std::cerr << command << ": unrecognized minimum gradient \"" << optarg << "\" specification." << std::endl; failed = true; } } else { std::cerr << command << ": illegal numeric format \"" << optarg << "\" for minimum gradient: " << enblend::errorMessage(errno) << std::endl; failed = true; } optionSet.insert(MinCurvatureOption); break; } case EdgeScaleId: { char* tail; boost::char_separator separator(NUMERIC_OPTION_DELIMITERS, "", boost::keep_empty_tokens); const std::string arg(optarg); boost::tokenizer > tokenizer(arg, separator); boost::tokenizer >::iterator token = tokenizer.begin(); if (token == tokenizer.end()) { std::cerr << command << ": no scale given to \"--contrast-edge-scale\". " << "scale is required." << std::endl; failed = true; } else { errno = 0; FilterConfig.edgeScale = strtod(token->c_str(), &tail); if (errno == 0) { if (*tail != 0) { std::cerr << command << ": could not decode \"" << tail << "\" in edge scale specification \"" << *token << "\" for edge scale." << std::endl; failed = true; } } else { std::cerr << command << ": illegal numeric format \"" << *token << "\" for edge scale: " << enblend::errorMessage(errno) << std::endl; failed = true; } ++token; } if (token != tokenizer.end()) { errno = 0; FilterConfig.lceScale = strtod(token->c_str(), &tail); if (errno == 0) { if (strcmp(tail, "%") == 0) { FilterConfig.lceScale *= FilterConfig.edgeScale / 100.0; } else if (*tail != 0) { std::cerr << command << ": could not decode \"" << tail << "\" in specification \"" << *token << "\" for LCE-scale." << std::endl; failed = true; } } else { std::cerr << command << ": illegal numeric format \"" << *token << "\" for LCE-Scale: " << enblend::errorMessage(errno) << std::endl; failed = true; } ++token; } if (token != tokenizer.end()) { errno = 0; FilterConfig.lceFactor = strtod(token->c_str(), &tail); if (errno == 0) { if (strcmp(tail, "%") == 0) { FilterConfig.lceFactor /= 100.0; } else if (*tail != 0) { std::cerr << command << ": could not decode \"" << tail << "\" in specification \"" << *token << "\" for LCE-factor." << std::endl; failed = true; } } else { std::cerr << command << ": illegal numeric format \"" << *token << "\" for LCE-factor: " << enblend::errorMessage(errno) << std::endl; failed = true; } ++token; } if (token != tokenizer.end()) { std::cerr << command << ": warning: ignoring trailing garbage \"" << *token << "\" in argument to \"--contrast-edge-scale\"" << std::endl; } optionSet.insert(EdgeScaleOption); break; } case EntropyCutoffId: { char* tail; boost::char_separator separator(NUMERIC_OPTION_DELIMITERS, "", boost::keep_empty_tokens); const std::string arg(optarg); boost::tokenizer > tokenizer(arg, separator); boost::tokenizer >::iterator token = tokenizer.begin(); if (token == tokenizer.end()) { std::cerr << command << ": no scale given to \"--entropy-cutoff\". " << "lower cutoff is required." << std::endl; failed = true; } else { errno = 0; EntropyLowerCutoff.set_value(strtod(token->c_str(), &tail)); if (errno == 0) { if (*tail == 0) { EntropyLowerCutoff.set_percentage(false); } else if (strcmp(tail, "%") == 0) { EntropyLowerCutoff.set_percentage(true); } else { std::cerr << command << ": unrecognized entropy's lower cutoff \"" << tail << "\" in \"" << *token << "\"" << std::endl; failed = true; } } else { std::cerr << command << ": illegal numeric format \"" << *token << "\" of entropy's lower cutoff: " << enblend::errorMessage(errno) << std::endl; failed = true; } ++token; } if (token != tokenizer.end()) { errno = 0; EntropyUpperCutoff.set_value(strtod(token->c_str(), &tail)); if (errno == 0) { if (*tail == 0) { EntropyUpperCutoff.set_percentage(false); } else if (strcmp(tail, "%") == 0) { EntropyUpperCutoff.set_percentage(true); } else { std::cerr << command << ": unrecognized entropy's upper cutoff \"" << tail << "\" in \"" << *token << "\"" << std::endl; failed = true; } } else { std::cerr << command << ": illegal numeric format \"" << *token << "\" of entropy's upper cutoff: " << enblend::errorMessage(errno) << std::endl; failed = true; } } if (token != tokenizer.end()) { std::cerr << command << ": warning: ignoring trailing garbage \"" << *token << "\" in argument to \"--entropy-cutoff\"" << std::endl; } optionSet.insert(EntropyCutoffOption); break; } case ExposureCutoffId: { char* tail; boost::char_separator separator(NUMERIC_OPTION_DELIMITERS, "", boost::keep_empty_tokens); const std::string arg(optarg); boost::tokenizer > tokenizer(arg, separator); boost::tokenizer >::iterator token = tokenizer.begin(); if (token == tokenizer.end()) { std::cerr << command << ": no value given to \"--exposure-cutoff\"; " << "lower cutoff is required." << std::endl; failed = true; } else { errno = 0; ExposureLowerCutoff.set_value(strtod(token->c_str(), &tail)); if (errno == 0) { if (*tail == 0) { ExposureLowerCutoff.set_percentage(false); } else if (strcmp(tail, "%") == 0) { ExposureLowerCutoff.set_percentage(true); } else { std::cerr << command << ": unrecognized exposure's lower cutoff \"" << tail << "\" in \"" << *token << "\"" << std::endl; failed = true; } } else { std::cerr << command << ": illegal numeric format \"" << *token << "\" of exposure's lower cutoff: " << enblend::errorMessage(errno) << std::endl; failed = true; } ++token; } if (token != tokenizer.end()) { errno = 0; ExposureUpperCutoff.set_value(strtod(token->c_str(), &tail)); if (errno == 0) { if (*tail == 0) { ExposureUpperCutoff.set_percentage(false); } else if (strcmp(tail, "%") == 0) { ExposureUpperCutoff.set_percentage(true); } else { std::cerr << command << ": unrecognized exposure's upper cutoff \"" << tail << "\" in \"" << *token << "\"" << std::endl; failed = true; } } else { std::cerr << command << ": illegal numeric format \"" << *token << "\" of exposure's upper cutoff: " << enblend::errorMessage(errno) << std::endl; failed = true; } ++token; } if (token != tokenizer.end()) { ExposureLowerCutoffGrayscaleProjector = *token; ++token; } if (token != tokenizer.end()) { ExposureUpperCutoffGrayscaleProjector = *token; ++token; } if (token != tokenizer.end()) { std::cerr << command << ": warning: ignoring trailing garbage \"" << *token << "\" in argument to \"--exposure-cutoff\"" << std::endl; } optionSet.insert(ExposureCutoffOption); break; } case CompressionId: if (optarg != nullptr && *optarg != 0) { std::string upper_opt(optarg); enblend::to_upper(upper_opt); if (upper_opt == "NONE") { ; // stick with default } else if (upper_opt == "DEFLATE" || upper_opt == "LZW" || upper_opt == "PACKBITS") { OutputCompression = upper_opt; } else if (upper_opt.find_first_not_of("0123456789") == std::string::npos) { OutputCompression = "JPEG QUALITY=" + upper_opt; } else if (enblend::starts_with(upper_opt, "JPEG") || enblend::starts_with(upper_opt, "JPEG-ARITH")) { const std::string::size_type delimiter_position = upper_opt.find_first_of(NUMERIC_OPTION_DELIMITERS); if (delimiter_position == std::string::npos) { if (upper_opt == "JPEG" || upper_opt == "JPEG-ARITH") { OutputCompression = upper_opt; } else { std::cerr << command << ": trailing garbage in JPEG compression \"" << optarg << "\"" << std::endl; failed = true; } } else { const std::string algorithm(upper_opt.substr(0, delimiter_position)); if (algorithm == "JPEG" || algorithm == "JPEG-ARITH") { const std::string level(upper_opt.substr(delimiter_position + 1U)); if (level.length() >= 1U && level.find_first_not_of("0123456789") == std::string::npos) { upper_opt.replace(delimiter_position, 1U, " QUALITY="); OutputCompression = upper_opt; } else { std::cerr << command << ": invalid JPEG compression level \"" << level << "\"" << std::endl; failed = true; } } else { std::cerr << command << ": unrecognized JPEG compression \"" << optarg << "\"" << std::endl; failed = true; } } } else { std::cerr << command << ": unrecognized compression \"" << optarg << "\"" << std::endl; failed = true; } } else { std::cerr << command << ": option \"--compression\" requires an argument" << std::endl; failed = true; } optionSet.insert(CompressionOption); break; case GrayProjectorId: if (optarg != nullptr && *optarg != 0) { GrayscaleProjector = optarg; } else { std::cerr << command << ": option \"--gray-projector\" requires an argument" << std::endl; failed = true; } optionSet.insert(GrayProjectorOption); break; case 'd': BOOST_FALLTHROUGH; case DepthId: if (optarg != nullptr && *optarg != 0) { OutputPixelType = enblend::outputPixelTypeOfString(optarg); } else { std::cerr << command << ": options \"-d\" or \"--depth\" require arguments" << std::endl; failed = true; } optionSet.insert(DepthOption); break; case 'o': BOOST_FALLTHROUGH; case OutputId: if (contains(optionSet, OutputOption)) { std::cerr << command << ": warning: more than one output file specified" << std::endl; } if (optarg != nullptr && *optarg != 0) { OutputFileName = optarg; } else { std::cerr << command << ": options \"-o\" or \"--output\" require arguments" << std::endl; failed = true; } optionSet.insert(OutputOption); break; case LoadMasksId: fill_mask_templates(optarg, SoftMaskTemplate, HardMaskTemplate, "--load-masks"); LoadMasks = true; optionSet.insert(LoadMasksOption); break; case SaveMasksId: fill_mask_templates(optarg, SoftMaskTemplate, HardMaskTemplate, "--save-masks"); SaveMasks = true; optionSet.insert(SaveMasksOption); break; case WeightExposureId: if (optarg != nullptr && *optarg != 0) { WExposure = enblend::numberOfString(optarg, [](double x) {return x >= 0.0;}, //< minimum-weight-exposure 0 "exposure weight less than 0; will use 0", 0.0, [](double x) {return x <= 1.0;}, //< maximum-weight-exposure 1 "exposure weight greater than 1; will use 1", 1.0); } else { std::cerr << command << ": option \"--exposure-weight\" requires an argument" << std::endl; failed = true; } optionSet.insert(ExposureWeightOption); break; case WeightContrastId: if (optarg != nullptr && *optarg != 0) { WContrast = enblend::numberOfString(optarg, [](double x) {return x >= 0.0;}, //< minimum-weight-contrast 0 "contrast weight less than 0; will use 0", 0.0, [](double x) {return x <= 1.0;}, //< maximum-weight-contrast 1 "contrast weight greater than 1; will use 1", 0.0); } else { std::cerr << command << ": option \"--contrast-weight\" requires an argument" << std::endl; failed = true; } optionSet.insert(ContrastWeightOption); break; case WeightSaturationId: if (optarg != nullptr && *optarg != 0) { WSaturation = enblend::numberOfString(optarg, [](double x) {return x >= 0.0;}, //< minimum-weight-saturation 0 "saturation weight less than 0; will use 0", 0.0, [](double x) {return x <= 1.0;}, //< maximum-weight-saturation 1 "saturation weight greater than 1; will use 1", 1.0); } else { std::cerr << command << ": option \"--saturation-weight\" requires an argument" << std::endl; failed = true; } WSaturationIsDefault = false; optionSet.insert(SaturationWeightOption); break; case ObsoleteExposureOptimumId: std::cerr << command << ": info: option \"--exposure-mu\" is obsolete, prefer \"--exposure-optimum\"" << std::endl; BOOST_FALLTHROUGH; case ExposureOptimumId: if (optarg != nullptr && *optarg != 0) { ExposureOptimum = enblend::numberOfString(optarg, [](double x) {return x >= 0.0;}, //< minimum-exposure-optimum 0 "exposure optimum value less than 0; will use 0", 0.0, [](double x) {return x <= 1.0;}, //< maximum-exposure-optimum 1 "exposure optimum value geater than 1; will use 1", 1.0); } else { std::cerr << command << ": option \"--exposure-optimum\" requires an argument" << std::endl; failed = true; } optionSet.insert(ExposureOptimumOption); break; case ObsoleteExposureWidthId: std::cerr << command << ": info: option \"--exposure-sigma\" is obsolete, prefer \"--exposure-width\"" << std::endl; BOOST_FALLTHROUGH; case ExposureWidthId: if (optarg != nullptr && *optarg != 0) { ExposureWidth = enblend::numberOfString(optarg, [](double x) {return x > 0.0;}, //< minimum-exposure-width 0 "exposure width less than 0; will use 1/1024", 1.0 / 1024.0); } else { std::cerr << command << ": option \"--exposure-width\" requires an argument" << std::endl; failed = true; } optionSet.insert(ExposureWidthOption); break; case ExposureWeightFunctionId: { const std::string arg(optarg); boost::char_separator separator(PATH_OPTION_DELIMITERS); boost::tokenizer > tokenizer(arg, separator); boost::tokenizer >::iterator token = tokenizer.begin(); if (token == tokenizer.end()) { std::cerr << command << ": option \"--exposure-weight-function\" requires an argument" << std::endl; failed = true; } else { ExposureWeightFunctionName = *token; ++token; #ifdef _WIN32 // special handling of absolute filenames on Windows if (ExposureWeightFunctionName.length() == 1U && arg.length() > 2U && arg[1] == ':' && token != tokenizer.end()) { ExposureWeightFunctionName.append(":"); ExposureWeightFunctionName.append(*token); ++token; } #endif } for (; token != tokenizer.end(); ++token) { ExposureWeightFunctionArguments.push_back(*token); } optionSet.insert(ExposureWeightFunctionOption); break; } case WeightEntropyId: if (optarg != nullptr && *optarg != 0) { WEntropy = enblend::numberOfString(optarg, [](double x) {return x >= 0.0;}, //< minimum-weight-entropy 0 "entropy weight less than 0; will use 0", 0.0, [](double x) {return x <= 1.0;}, //< maximum-weight-entropy 1 "entropy weight greater than 1; will use 1", 1.0); } else { std::cerr << command << ": option \"--entropy-weight\" requires an argument" << std::endl; failed = true; } optionSet.insert(EntropyWeightOption); break; case 'v': BOOST_FALLTHROUGH; case VerboseId: if (optarg != nullptr && *optarg != 0) { Verbose = enblend::numberOfString(optarg, [](int x) {return x >= 0;}, //< minimum-verbosity-level 0 "verbosity level less than 0; will use 0", 0); } else { Verbose++; } optionSet.insert(VerboseOption); break; case ContrastWindowSizeId: if (optarg != nullptr && *optarg != 0) { ContrastWindowSize = enblend::numberOfString(optarg, [](int x) {return x >= 3;}, //< minimum-contrast-window-size 3 "contrast window size to small; will use size = 3", 3); if (ContrastWindowSize % 2 != 1) { std::cerr << command << ": warning: contrast window size \"" << ContrastWindowSize << "\" is even; increasing size to next odd number" << std::endl; ContrastWindowSize++; } } else { std::cerr << command << ": option \"--contrast-window-size\" requires an argument" << std::endl; failed = true; } optionSet.insert(ContrastWindowSizeOption); break; case EntropyWindowSizeId: if (optarg != nullptr && *optarg != 0) { EntropyWindowSize = enblend::numberOfString(optarg, [](int x) {return x >= 3;}, //< minimum-entropy-window-size 3 "entropy window size to small; will use size = 3", 3); if (EntropyWindowSize % 2 != 1) { std::cerr << command << ": warning: entropy window size \"" << EntropyWindowSize << "\" is even; increasing size to next odd number" << std::endl; EntropyWindowSize++; } } else { std::cerr << command << ": option \"--entropy-window-size\" requires an argument" << std::endl; failed = true; } optionSet.insert(EntropyWindowSizeOption); break; case BlendColorspaceId: if (optarg != nullptr && *optarg != 0) { std::string name(optarg); enblend::to_upper(name); if (name == "IDENTITY" || name == "ID" || name == "UNIT") { BlendColorspace = IdentitySpace; } else if (name == "LAB" || name == "CIELAB" || name == "LSTAR" || name == "L-STAR") { BlendColorspace = CIELAB; } else if (name == "LUV" || name == "CIELUV") { BlendColorspace = CIELUV; } else if (name == "CIECAM" || name == "CIECAM02" || name == "JCH") { BlendColorspace = CIECAM; } else { std::cerr << command << ": unrecognized argument \"" << optarg << "\" of option \"--blend-colorspace\"" << std::endl; failed = true; } } else { std::cerr << command << ": option \"--blend-colorspace\" requires an argument" << std::endl; failed = true; } optionSet.insert(BlendColorspaceOption); break; case 'c': BOOST_FALLTHROUGH; case CiecamId: std::cerr << command << ": info: option \"--ciecam\" will be withdrawn in the next release\n" << command << ": note: prefer option \"--blend-colorspace\" to \"--ciecam\"" << std::endl; BlendColorspace = CIECAM; optionSet.insert(CIECAM02Option); break; case NoCiecamId: std::cerr << command << ": info: option \"--no-ciecam\" will be withdrawn in the next release\n" << command << ": note: prefer option \"--blend-colorspace\" to \"--no-ciecam\"" << std::endl; BlendColorspace = IdentitySpace; optionSet.insert(NoCIECAM02Option); break; case FallbackProfileId: if (enblend::can_open_file(optarg)) { FallbackProfile = cmsOpenProfileFromFile(optarg, "r"); if (FallbackProfile == nullptr) { std::cerr << command << ": failed to open fallback ICC profile file \"" << optarg << "\"\n"; exit(1); } } else { exit(1); } optionSet.insert(FallbackProfileOption); break; case 'f': if (optarg != nullptr && *optarg != 0) { const int n = sscanf(optarg, "%dx%d+%d+%d", &OutputWidthCmdLine, &OutputHeightCmdLine, &OutputOffsetXCmdLine, &OutputOffsetYCmdLine); if (n == 4) { ; // ok: full geometry string } else if (n == 2) { OutputOffsetXCmdLine = 0; OutputOffsetYCmdLine = 0; } else { std::cerr << command << ": option \"-f\" requires 2 or 4 arguments" << std::endl; failed = true; } } else { std::cerr << command << ": option \"-f\" requires 2 or 4 arguments" << std::endl; failed = true; } OutputSizeGiven = true; optionSet.insert(SizeAndPositionOption); break; case 'g': GimpAssociatedAlphaHack = true; optionSet.insert(AssociatedAlphaOption); break; case 'l': BOOST_FALLTHROUGH; case LevelsId: if (optarg != nullptr && *optarg != 0) { std::string levels(optarg); enblend::to_upper(levels); if (levels == "AUTO" || levels == "AUTOMATIC") { ExactLevels = 0; } else if (levels.find_first_not_of("+-0123456789") != std::string::npos) { std::cerr << command << ": options \"-l\" or \"--levels\" require an integer argument or \"auto\"" << std::endl; failed = true; } else { std::ostringstream oss; oss << "cannot use more than " << MAX_PYRAMID_LEVELS << " pyramid levels; will use at most " << MAX_PYRAMID_LEVELS << " levels"; ExactLevels = enblend::numberOfString(optarg, [](int x) {return x != 0;}, "cannot blend with zero levels; will use one level", 1, [](int x) {return x <= MAX_PYRAMID_LEVELS;}, oss.str(), MAX_PYRAMID_LEVELS); } } else { std::cerr << command << ": options \"-l\" or \"--levels\" require an argument" << std::endl; failed = true; } optionSet.insert(LevelsOption); break; case LayerSelectorId: { selector::algorithm_list::const_iterator selector = selector::find_by_name(optarg); if (selector != selector::algorithms.end()) { LayerSelection.set_selector(selector->get()); } else { std::cerr << command << ": unknown selector algorithm \"" << optarg << "\""; exit(1); } optionSet.insert(LayerSelectorOption); break; } case ParameterId: { boost::char_separator separator(NUMERIC_OPTION_DELIMITERS, "", boost::keep_empty_tokens); const std::string arg(optarg); boost::tokenizer > tokenizer(arg, separator); boost::tokenizer >::iterator token = tokenizer.begin(); for (auto token = tokenizer.begin(); token != tokenizer.end(); ++token) { std::string key; std::string value; size_t delimiter = token->find_first_of(ASSIGNMENT_CHARACTERS); if (delimiter == std::string::npos) { key = *token; value.assign("1"); } else { key = token->substr(0, delimiter); value = token->substr(delimiter + 1); if (value.empty()) { std::cerr << command << ": parameter key \"" << key << "\" lacks a value;\n" << command << ": note: dangling assignment operator\n"; exit(1); } } enblend::trim(key); enblend::trim(value); if (parameter::is_valid_identifier(key)) { parameter::insert(key, value); } else { std::cerr << command << ": parameter key \"" << key << "\" is not a valid identifier\n"; exit(1); } } break; } case NoParameterId: { boost::char_separator separator(NUMERIC_OPTION_DELIMITERS, "", boost::keep_empty_tokens); const std::string arg(optarg); boost::tokenizer > tokenizer(arg, separator); boost::tokenizer >::iterator token = tokenizer.begin(); for (auto token = tokenizer.begin(); token != tokenizer.end(); ++token) { std::string key(*token); enblend::trim(key); if (key == "*") { parameter::erase_all(); } else if (parameter::is_valid_identifier(key)) { parameter::erase(key); } else { std::cerr << command << ": warning: key \"" << key << "\" is not a valid identifier; ignoring\n"; } } break; } case '?': { if (optopt == 0 || optopt == -1) { const int failing_index = optind - 1; std::cerr << command << ": unknown long option"; if (failing_index >= 0 && failing_index < argc) { std::cerr << " \"" << argv[failing_index] << "\""; } std::cerr << std::endl; } else { const struct option* failing_long_option = lookup_long_option_by_id(long_options, optopt); if (failing_long_option == nullptr) { if (short_option_requires_argument(short_options, optopt)) { std::cerr << command << ": option \"-" << static_cast(optopt) << "\" requires an argument" << std::endl; } else { std::cerr << command << ": unknown option "; if (isprint(optopt)) { std::cerr << "\"-" << static_cast(optopt) << "\""; } else { std::cerr << "character 0x" << std::hex << optopt; } std::cerr << std::endl; } } else { assert(failing_long_option->has_arg == required_argument); std::cerr << command << ": option \"--" << failing_long_option->name << "\" requires an argument" << std::endl; } } std::cerr << "Try \"enfuse --help\" for more information." << std::endl; exit(1); } default: std::cerr << command << ": internal error: unhandled command line option" << std::endl; exit(1); } } if (contains(optionSet, SaveMasksOption) && contains(optionSet, LoadMasksOption)) { std::cerr << command << ": options \"--load-masks\" and \"--save-masks\" are mutually exclusive" << std::endl; failed = true; } if (failed) { exit(1); } switch (print_only_task) { case VERSION_ONLY: #ifdef _MSC_VER // deinstall failure hook to catch errors in printVersion directly // so printVersion can run to end __pfnDliFailureHook2 = nullptr; #endif introspection::printVersion(argc, argv); break; // never reached case USAGE_ONLY: printUsage(false); break; // never reached case IMAGE_FORMATS_ONLY: introspection::printImageFormats(); break; // never reached case SIGNATURE_ONLY: introspection::printSignature(); break; // never reached case GLOBBING_ALGOS_ONLY: introspection::printGlobbingAlgos(); break; // never reached case SOFTWARE_COMPONENTS_ONLY: introspection::printSoftwareComponents(); break; // never reached case GPU_INFO_COMPONENTS_ONLY: #ifdef OPENCL std::cout << "Available, OpenCL-compatible platform(s) and their device(s)\n"; ocl::print_opencl_information(); ocl::print_gpu_preference(preferredGPUPlatform, preferredGPUDevice); exit(0); #else std::cerr << command << ": option \"--show-gpu-info\" is not implemented in this binary,\n" << command << ": because it was compiled without support for OpenCL" << std::endl; exit(1); #endif break; // never reached case PROCESS_COMPLETELY: break; default: NEVER_REACHED("switch control expression \"print_only_task\" out of range"); } StopAfterMaskGeneration = contains(optionSet, SaveMasksOption) && !contains(optionSet, OutputOption); warn_of_ineffective_options(optionSet); #ifdef OPENCL if (UseGPU) { initialize_gpu_subsystem(preferredGPUPlatform, preferredGPUDevice); } #endif // OPENCL if (WExposure > 0.0) { ExposureWeightFunction = exposure_weight::make_weight_function(ExposureWeightFunctionName, ExposureWeightFunctionArguments.begin(), ExposureWeightFunctionArguments.end(), ExposureOptimum, ExposureWidth); const exposure_weight::weight_function_check_t check_result = exposure_weight::check_weight_function(ExposureWeightFunction); if (check_result != exposure_weight::OK) { std::cerr << command << ": unusable exposure weight function \"" << ExposureWeightFunctionName << "\"\n"; switch (check_result) { case exposure_weight::NEGATIVE: std::cerr << command << ": note: at least one weight is negative" << std::endl; exit(1); case exposure_weight::NON_UNIT: std::cerr << command << ": note: at least one weight is larger than one" << std::endl; exit(1); case exposure_weight::DEGENERATE: std::cerr << command << ": note: too many zeros" << std::endl; exit(1); case exposure_weight::OK: throw never_reached("case indicates OK in error handler switch-expression"); } } } if (parameter::as_boolean("dump-exposure-weight-function", false)) { const int n = parameter::as_integer("exposure-weight-function-points", 21); exposure_weight::dump_weight_function(ExposureWeightFunction, std::min(std::max(n, 10), 10000)); exit(0); } return optind; } int main(int argc, char** argv) { #ifdef _MSC_VER // Make sure the FPU is set to rounding mode so that the lrint // functions in float_cast.h will work properly. // See changes in vigra numerictraits.hxx _controlfp(_RC_NEAR, _MCW_RC); // install failure hook for delayed loading of dll __pfnDliFailureHook2 = delayHookFailureFunc; #else fesetround(FE_TONEAREST); #endif #ifndef _WIN32 sigemptyset(&SigintMask); sigaddset(&SigintMask, SIGINT); struct sigaction action; action.sa_handler = sigint_handler; action.sa_flags = 0; sigemptyset(&(action.sa_mask)); sigaction(SIGINT, &action, nullptr); #else signal(SIGINT, sigint_handler); #endif if (atexit(cleanup_output) != 0) { std::cerr << command << ": warning: could not install cleanup routine\n"; } sig.initialize(); gsl_set_error_handler_off(); TIFFSetWarningHandler(tiff_warning); TIFFSetErrorHandler(tiff_error); //< layer-selector all-layers LayerSelection.set_selector(selector::find_by_id(selector::id_t::AllLayersId)->get()); if (!getopt_long_works_ok()) { std::cerr << command << ": cannot reliably parse command line; giving up\n"; exit(1); } int optind; try { optind = process_options(argc, argv); } catch (vigra::StdException& e) { std::cerr << command << ": error while processing command line options\n" << command << ": " << e.what() << std::endl; exit(1); } enblend::TraceableFileNameList inputTraceableFileNameList; // Remaining parameters are input files. while (optind < argc) { enblend::TraceableFileNameList files; enblend::unfold_filename(files, std::string(argv[optind])); inputTraceableFileNameList.insert(inputTraceableFileNameList.end(), files.begin(), files.end()); optind++; } if (inputTraceableFileNameList.empty()) { std::cerr << command << ": no input files specified\n"; exit(1); } if (parameter::as_boolean("dump-global-variables", false)) { DUMP_GLOBAL_VARIABLES(); } sig.check(); for (enblend::TraceableFileNameList::iterator i = inputTraceableFileNameList.begin(); i != inputTraceableFileNameList.end(); ++i) { if (!enblend::can_open_file((*i)->filename())) { (*i)->unroll_trace(); exit(1); } if (!vigra::isImage((*i)->filename().c_str())) { std::cerr << command << ": cannot process \"" << (*i)->filename() << "\"; not recognized as an image\n" << command << ": info: possible causes:\n" << command << ": info: - An underlying image-processing library does not understand the\n" << command << ": info: particular compression, sub-format, format extension, ...\n" << command << ": info: - Enfuse was not compiled with support for this format, which\n" << command << ": info: can be checked with \"" << command << " --show-image-formats\".\n" << command << ": info: - The image is corrupted or it is incomplete/truncated.\n" << command << ": info: - It really is not an image. Honesty, huh?\n"; (*i)->unroll_trace(); exit(1); } } LayerSelection.retrieve_image_information(inputTraceableFileNameList.begin(), inputTraceableFileNameList.end()); // List of info structures for each input image. std::list imageInfoList; std::list::iterator imageInfoIterator; bool isColor = false; std::string pixelType; TiffResolution resolution; vigra::ImageImportInfo::ICCProfile iccProfile; vigra::Rect2D inputUnion; selector::layer_ordered_list_t viable_layers; selector::layer_ordered_list_t::const_iterator layer; unsigned layers = 0; // total number of layers in image file enblend::FileNameList inputFileNameList; enblend::TraceableFileNameList::iterator inputFileNameIterator = inputTraceableFileNameList.begin(); while (inputFileNameIterator != inputTraceableFileNameList.end()) { const std::string filename((*inputFileNameIterator)->filename()); vigra::ImageImportInfo* inputInfo = nullptr; try { vigra::ImageImportInfo info(filename.c_str()); if (layers == 0) { // OPTIMIZATION: call only once per file layers = info.numImages(); LayerSelection.set_selector((*inputFileNameIterator)->selector()); viable_layers.clear(); viable_layers = LayerSelection.viable_layers(filename); layer = viable_layers.begin(); #ifdef DEBUG_FILESPEC std::cout << "+ viable_layers(" << filename << ") are [ "; std::copy(viable_layers.begin(), viable_layers.end(), std::ostream_iterator(std::cout, " ")); std::cout << "]\n"; #endif } inputInfo = new vigra::ImageImportInfo(info); } catch (vigra::ContractViolation& exception) { std::cerr << command << ": cannot load image \"" << filename << "\"\n" << command << ": " << exception.what() << "\n"; if (enblend::maybe_response_file(filename)) { std::cerr << command << ": note: maybe you meant a response file and forgot the initial '" << RESPONSE_FILE_PREFIX_CHAR << "'?\n"; } exit(1); } assert(layer != viable_layers.end()); inputInfo->setImageIndex(*layer - 1); if (Verbose >= VERBOSE_LAYER_SELECTION) { std::cerr << command << ": info: layer selector \"" << LayerSelection.name() << "\" accepts\n" << command << ": info: layer " << *layer << " of " << layers << " in image \"" << filename << "\"\n"; } // Save this image info in the list. imageInfoList.push_back(inputInfo); inputFileNameList.push_back(filename); if (Verbose >= VERBOSE_INPUT_IMAGE_INFO_MESSAGES) { std::cerr << command << ": info: input image \"" << (*inputFileNameIterator)->filename() << "\" " << *layer << '/' << layers << ' '; if (inputInfo->isColor()) { std::cerr << "RGB "; } if (!inputInfo->getICCProfile().empty()) { std::cerr << "ICC "; } std::cerr << inputInfo->getPixelType() << " position=" << inputInfo->getPosition().x << "x" << inputInfo->getPosition().y << " " << "size=" << inputInfo->width() << "x" << inputInfo->height() << std::endl; } if (inputInfo->numExtraBands() < 1) { // Complain about lack of alpha channel. std::cerr << command << ": info: input image \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << " does not have an alpha channel;\n"; (*inputFileNameIterator)->unroll_trace(); std::cerr << command << ": note: assuming all pixels should contribute to the final image" << std::endl; } // Get input image's position and size. vigra::Rect2D imageROI(vigra::Point2D(inputInfo->getPosition()), vigra::Size2D(inputInfo->width(), inputInfo->height())); if (inputFileNameIterator == inputTraceableFileNameList.begin()) { // First input image inputUnion = imageROI; isColor = inputInfo->isColor(); pixelType = inputInfo->getPixelType(); resolution = TiffResolution(inputInfo->getXResolution(), inputInfo->getYResolution()); iccProfile = inputInfo->getICCProfile(); if (!iccProfile.empty()) { InputProfile = cmsOpenProfileFromMem(iccProfile.data(), iccProfile.size()); if (InputProfile == nullptr) { std::cerr << std::endl << command << ": error parsing ICC profile data from file \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << std::endl; (*inputFileNameIterator)->unroll_trace(); exit(1); } } } else { // Second and later images inputUnion |= imageROI; if (isColor != inputInfo->isColor()) { std::cerr << command << ": input image \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << " is " << (inputInfo->isColor() ? "color" : "grayscale") << "\n" << command << ": but previous images are " << (isColor ? "color" : "grayscale") << std::endl; (*inputFileNameIterator)->unroll_trace(); exit(1); } if (pixelType != inputInfo->getPixelType()) { std::cerr << command << ": input image \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << " has pixel type " << inputInfo->getPixelType() << ",\n" << command << ": but previous images have pixel type " << pixelType << std::endl; (*inputFileNameIterator)->unroll_trace(); exit(1); } if (resolution != TiffResolution(inputInfo->getXResolution(), inputInfo->getYResolution())) { std::cerr << command << ": info: input image \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << " has resolution " << inputInfo->getXResolution() << " dpi x " << inputInfo->getYResolution() << " dpi,\n" << command << ": info: but first image has resolution " << resolution.x << " dpi x " << resolution.y << " dpi" << std::endl; (*inputFileNameIterator)->unroll_trace(); } if (iccProfile != inputInfo->getICCProfile()) { vigra::ImageImportInfo::ICCProfile mismatchProfile(inputInfo->getICCProfile()); cmsHPROFILE newProfile = nullptr; if (!mismatchProfile.empty()) { newProfile = cmsOpenProfileFromMem(mismatchProfile.data(), mismatchProfile.size()); if (newProfile == nullptr) { std::cerr << std::endl << command << ": error parsing ICC profile data from file \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << std::endl; (*inputFileNameIterator)->unroll_trace(); exit(1); } } if (InputProfile == nullptr || newProfile == nullptr || enblend::profileDescription(InputProfile) != enblend::profileDescription(newProfile)) { const std::string category(BlendColorspace <= IdentitySpace ? "warning" : "info"); std::cerr << std::endl << command << ": " << category << ": input image \"" << (*inputFileNameIterator)->filename() << "\"" << enblend::optional_layer_name(*layer, layers) << "\n"; (*inputFileNameIterator)->unroll_trace(); std::cerr << command << ": " << category << ": has "; if (newProfile) { std::cerr << "ICC profile \"" << enblend::profileDescription(newProfile) << "\",\n"; } else { std::cerr << "no ICC profile,\n"; } std::cerr << command << ": " << category << ": but first image has "; if (InputProfile) { std::cerr << "ICC profile \"" << enblend::profileDescription(InputProfile) << "\";\n"; } else { std::cerr << "no ICC profile;\n"; } if (BlendColorspace <= IdentitySpace) { std::cerr << command << ": " << category << ": blending images with different color spaces\n" << command << ": " << category << ": may have unexpected results\n"; } } } } ++layer; if (layer == viable_layers.end()) { #ifdef DEBUG_FILESPEC std::cout << "+ next image\n"; #endif layers = 0; ++inputFileNameIterator; } else { #ifdef DEBUG_FILESPEC std::cout << "+ next layer\n"; #endif // We are about to process the next layer in the _same_ // image. The imageInfoList already has been updated, but // inputTraceableFileNameList still lacks the filename. inputTraceableFileNameList.insert(inputFileNameIterator, (*inputFileNameIterator)->clone()); } } // Check that more than one input file was given. if (imageInfoList.size() <= 1) { const size_t n = inputTraceableFileNameList.size(); const size_t m = imageInfoList.size(); if (n > m) { std::cerr << command << ": warning: selector has rejected " << n - m << " out of " << n << " images\n"; } switch (m) { case 0: std::cerr << command << ": no input images given\n"; exit(1); break; case 1: std::cerr << command << ": warning: only one input image given;\n" << command << ": note: Enfuse needs two or more overlapping input images in order to do\n" << command << ": note: blending calculations. The output will be the same as the input.\n"; break; } } if (resolution == TiffResolution()) { std::cerr << command << ": warning: no usable resolution found in first image \"" << (*inputTraceableFileNameList.begin())->filename() << "\";\n" << command << ": note: Enfuse will assume " << DEFAULT_TIFF_RESOLUTION << " dpi\n"; ImageResolution = TiffResolution(DEFAULT_TIFF_RESOLUTION, DEFAULT_TIFF_RESOLUTION); } else { ImageResolution = resolution; } // Create the Info for the output file. vigra::ImageExportInfo outputImageInfo(OutputFileName.c_str()); if (!StopAfterMaskGeneration) { OutputIsValid = false; // Make sure that inputUnion is at least as big as given by the -f paramater. if (OutputSizeGiven) { inputUnion |= vigra::Rect2D(OutputOffsetXCmdLine, OutputOffsetYCmdLine, OutputOffsetXCmdLine + OutputWidthCmdLine, OutputOffsetYCmdLine + OutputHeightCmdLine); } if (!OutputCompression.empty()) { outputImageInfo.setCompression(OutputCompression.c_str()); } // If not overridden by the command line, the pixel type of the // output image is the same as the input images'. If the pixel // type is not supported by the output format, replace it with the // best match. { const std::string outputFileType = enblend::getFileType(OutputFileName); const std::string neededPixelType = OutputPixelType.empty() ? std::string(pixelType) : OutputPixelType; const std::string bestPixelType = enblend::bestPixelType(outputFileType, neededPixelType); if (neededPixelType != bestPixelType) { std::cerr << command << ": warning: " << (OutputPixelType.empty() ? "deduced" : "requested") << " output pixel type is \"" << neededPixelType << "\", but image type \"" << outputFileType << "\"\n" << command << ": warning: supports \"" << bestPixelType << "\" at best; will use \"" << bestPixelType << "\"" << std::endl; } outputImageInfo.setPixelType(bestPixelType.c_str()); pixelType = enblend::maxPixelType(pixelType, bestPixelType); } // Set the output image ICC profile outputImageInfo.setICCProfile(iccProfile); if (BlendColorspace == UndeterminedColorspace && !(iccProfile.empty() || enblend::isFloatingPoint(pixelType))) { BlendColorspace = CIELUV; } if (BlendColorspace == CIECAM || BlendColorspace == CIELAB || BlendColorspace == CIELUV) { if (enblend::isFloatingPoint(pixelType)) { std::cerr << command << ": warning: blend color space for floating-point images is not \"identity\"" << std::endl; } if (InputProfile == nullptr) { std::cerr << command << ": warning: input images do not have ICC profiles;\n"; if (FallbackProfile == nullptr) { std::cerr << command << ": warning: assuming sRGB profile" << std::endl; InputProfile = cmsCreate_sRGBProfile(); } else { std::cerr << command << ": warning: using fallback profile \"" << enblend::profileDescription(FallbackProfile) << "\"" << std::endl; InputProfile = FallbackProfile; FallbackProfile = nullptr; // avoid double freeing } } XYZProfile = cmsCreateXYZProfile(); const unsigned input_profile_type = enblend::profileChannels(InputProfile) > 1 ? TYPE_RGB_DBL : TYPE_GRAY_DBL; InputToXYZTransform = cmsCreateTransform(InputProfile, input_profile_type, XYZProfile, TYPE_XYZ_DBL, RENDERING_INTENT_FOR_BLENDING, TRANSFORMATION_FLAGS_FOR_BLENDING); if (InputToXYZTransform == nullptr) { std::cerr << command << ": error building color transform from \"" << enblend::profileName(InputProfile) << " " << enblend::profileDescription(InputProfile) << "\" to XYZ space" << std::endl; exit(1); } XYZToInputTransform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL, InputProfile, input_profile_type, RENDERING_INTENT_FOR_BLENDING, TRANSFORMATION_FLAGS_FOR_BLENDING); if (XYZToInputTransform == nullptr) { std::cerr << command << ": error building color transform from XYZ space to \"" << enblend::profileName(InputProfile) << " " << enblend::profileDescription(InputProfile) << "\"" << std::endl; exit(1); } // P2 Viewing Conditions: D50, 500 lumens ViewingConditions.whitePoint.X = XYZ_SCALE * cmsD50_XYZ()->X; ViewingConditions.whitePoint.Y = XYZ_SCALE * cmsD50_XYZ()->Y; ViewingConditions.whitePoint.Z = XYZ_SCALE * cmsD50_XYZ()->Z; ViewingConditions.Yb = 20.0; ViewingConditions.La = 31.83; ViewingConditions.surround = AVG_SURROUND; ViewingConditions.D_value = 1.0; CIECAMTransform = cmsCIECAM02Init(nullptr, &ViewingConditions); if (!CIECAMTransform) { std::cerr << std::endl << command << ": error initializing CIECAM02 transform" << std::endl; exit(1); } cmsCIExyY white_point; if (cmsIsTag(InputProfile, cmsSigMediaWhitePointTag)) { cmsXYZ2xyY(&white_point, (const cmsCIEXYZ*) cmsReadTag(InputProfile, cmsSigMediaWhitePointTag)); if (Verbose >= VERBOSE_COLOR_CONVERSION_MESSAGES) { double temperature; cmsTempFromWhitePoint(&temperature, &white_point); std::cerr << command << ": info: using white point of input profile at " << temperature << "K" << std::endl; } } else { memcpy(&white_point, cmsD50_xyY(), sizeof(cmsCIExyY)); if (Verbose >= VERBOSE_COLOR_CONVERSION_MESSAGES) { double temperature; cmsTempFromWhitePoint(&temperature, &white_point); std::cerr << command << ": info: falling back to predefined (D50) white point at " << temperature << "K" << std::endl; } } LabProfile = cmsCreateLab2Profile(&white_point); InputToLabTransform = cmsCreateTransform(InputProfile, input_profile_type, LabProfile, TYPE_Lab_DBL, RENDERING_INTENT_FOR_BLENDING, TRANSFORMATION_FLAGS_FOR_BLENDING); if (!InputToLabTransform) { std::cerr << command << ": error building color transform from \"" << enblend::profileName(InputProfile) << " " << enblend::profileDescription(InputProfile) << "\" to Lab space" << std::endl; exit(1); } LabToInputTransform = cmsCreateTransform(LabProfile, TYPE_Lab_DBL, InputProfile, input_profile_type, RENDERING_INTENT_FOR_BLENDING, TRANSFORMATION_FLAGS_FOR_BLENDING); if (!LabToInputTransform) { std::cerr << command << ": error building color transform from Lab space to \"" << enblend::profileName(InputProfile) << " " << enblend::profileDescription(InputProfile) << "\"" << std::endl; exit(1); } } else { if (FallbackProfile != nullptr) { std::cerr << command << ": warning: fusing in identity space; option \"--fallback-profile\" has no effect" << std::endl; } } // The size of the output image. if (Verbose >= VERBOSE_INPUT_UNION_SIZE_MESSAGES) { std::cerr << command << ": info: output image size: " << inputUnion << std::endl; } // Set the output image position and resolution. outputImageInfo.setXResolution(ImageResolution.x); outputImageInfo.setYResolution(ImageResolution.y); outputImageInfo.setPosition(inputUnion.upperLeft()); // Sanity check on the output image file. try { // This seems to be a reasonable way to check if // the output file is going to work after blending // is done. encoder(outputImageInfo); } catch (vigra::StdException& e) { std::cerr << std::endl << command << ": error opening output file \"" << OutputFileName << "\";\n" << command << ": " << e.what() << std::endl; exit(1); } if (!OutputPixelType.empty()) { pixelType = enblend::maxPixelType(pixelType, OutputPixelType); } } // Invoke templatized blender. try { if (isColor) { if (pixelType == "UINT8") enblend::enfuseMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); #ifndef DEBUG_8BIT_ONLY else if (pixelType == "UINT16") enblend::enfuseMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "INT16") enblend::enfuseMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "UINT32") enblend::enfuseMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "INT32") enblend::enfuseMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "FLOAT") enblend::enfuseMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "DOUBLE") enblend::enfuseMain >(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); #endif else { std::cerr << command << ": RGB images with pixel type \"" << pixelType << "\" are not supported" << std::endl; exit(1); } } else { if (!WSaturationIsDefault && (WSaturation != 0.0)) { std::cerr << command << ": warning: \"--WSaturation\" is not applicable to grayscale images;\n" << command << ": warning: this parameter will have no effect" << std::endl; WSaturation = 0.0; } if (pixelType == "UINT8") enblend::enfuseMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); #ifndef DEBUG_8BIT_ONLY else if (pixelType == "UINT16") enblend::enfuseMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "INT16") enblend::enfuseMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "UINT32") enblend::enfuseMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "INT32") enblend::enfuseMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "FLOAT") enblend::enfuseMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); else if (pixelType == "DOUBLE") enblend::enfuseMain(inputFileNameList, imageInfoList, outputImageInfo, inputUnion); #endif else { std::cerr << command << ": black&white images with pixel type \"" << pixelType << "\" are not supported" << std::endl; exit(1); } } for (auto x : imageInfoList) { delete x; } for (auto x : inputTraceableFileNameList) { delete x; } } catch (std::bad_alloc& e) { std::cerr << std::endl << command << ": out of memory\n" << command << ": " << e.what() << std::endl; exit(1); } catch (vigra::StdException& e) { std::cerr << std::endl << command << ": an exception occured\n" << command << ": " << e.what() << std::endl; exit(1); } #ifdef OPENCL delete GPUContext; #endif // OPENCL if (FallbackProfile) {cmsCloseProfile(FallbackProfile);} if (LabProfile) {cmsCloseProfile(LabProfile);} if (InputToLabTransform) {cmsCIECAM02Done(InputToLabTransform);} if (LabToInputTransform) {cmsCIECAM02Done(LabToInputTransform);} if (CIECAMTransform) {cmsCIECAM02Done(CIECAMTransform);} if (InputToXYZTransform) {cmsDeleteTransform(InputToXYZTransform);} if (XYZToInputTransform) {cmsDeleteTransform(XYZToInputTransform);} if (XYZProfile) {cmsCloseProfile(XYZProfile);} if (InputProfile) {cmsCloseProfile(InputProfile);} delete ExposureWeightFunction; // Success. return 0; } enblend-enfuse-4.2/src/openmp_lock.h0000644000175000017500000000576412641706002014452 00000000000000/* * Copyright (C) 2013-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OPENMP_LOCK_H_INCLUDED_ #define OPENMP_LOCK_H_INCLUDED_ #ifdef HAVE_CONFIG_H #include #endif #include "openmp_def.h" namespace omp { #ifdef OPENMP class lock { public: lock() {omp_init_lock(&lock_);} ~lock() {omp_destroy_lock(&lock_);} lock(const lock&) = delete; lock& operator=(const lock&) = delete; void set() {omp_set_lock(&lock_);} void unset() {omp_unset_lock(&lock_);} bool test() {return omp_test_lock(&lock_) != 0;} private: omp_lock_t lock_; }; class nestable_lock { public: nestable_lock() {omp_init_nest_lock(&lock_);} ~nestable_lock() {omp_destroy_nest_lock(&lock_);} nestable_lock(const nestable_lock&) = delete; nestable_lock& operator=(const nestable_lock&) = delete; void set() {omp_set_nest_lock(&lock_);} void unset() {omp_unset_nest_lock(&lock_);} bool test() {return omp_test_nest_lock(&lock_) != 0;} private: omp_nest_lock_t lock_; }; #else class lock { public: lock() {} ~lock() {} lock(const lock&) = delete; lock& operator=(const lock&) = delete; void set() {} void unset() {} bool test() {return false;} }; class nestable_lock { public: nestable_lock() {} ~nestable_lock() {} nestable_lock(const nestable_lock&) = delete; nestable_lock& operator=(const nestable_lock&) = delete; void set() {} void unset() {} bool test() {return false;} }; #endif // OPENMP template class scoped_lock { public: scoped_lock() = delete; explicit scoped_lock(basic_lock& a_lock) : lock_(&a_lock) {lock_->set();} ~scoped_lock() {lock_->unset();} scoped_lock(const scoped_lock&) = delete; scoped_lock& operator=(const scoped_lock&) = delete; void set() {lock_->set();} void unset() {lock_->unset();} bool test() {return lock_->test();} private: basic_lock* const lock_; }; // class scoped_lock } // namespace omp #endif // OPENMP_LOCK_H_INCLUDED_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/timer.cc0000644000175000017500000001320312641706002013405 00000000000000/* * Copyright (C) 2013-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "timer.h" namespace timer { inline static double clock_in_seconds(clock_t a_clock_time) { return static_cast(a_clock_time) / static_cast(CLOCKS_PER_SEC); } StandardWallClock::StandardWallClock() { start(); } void StandardWallClock::start() { value_ = clock_t(); start_ = clock(); stop_ = start_; } void StandardWallClock::stop() { stop_ = clock(); value_ += stop_ - start_; start_ = stop_; } void StandardWallClock::restart() { start_ = clock(); stop_ = start_; } double StandardWallClock::value() const { return clock_in_seconds(value_); } #ifdef HAVE_CLOCK_GETTIME inline static std::uint64_t timespec_in_nano_seconds(const struct timespec& a_timespec) { return static_cast(a_timespec.tv_sec) * 1000000000UL + static_cast(a_timespec.tv_nsec); } RealTimeWallClock::RealTimeWallClock() { start(); } void RealTimeWallClock::start() { value_ = value_t(); clock_gettime(CLOCK_REALTIME, &start_); stop_.tv_sec = start_.tv_sec; stop_.tv_nsec = long(); } void RealTimeWallClock::stop() { clock_gettime(CLOCK_REALTIME, &stop_); value_ += timespec_in_nano_seconds(stop_) - timespec_in_nano_seconds(start_); start_ = stop_; } void RealTimeWallClock::restart() { clock_gettime(CLOCK_REALTIME, &start_); stop_ = start_; } double RealTimeWallClock::value() const { return static_cast(value_) * 1e-9; } #endif // HAVE_CLOCK_GETTIME #ifdef WIN32 inline static ULONGLONG filetime_in_100nanoseconds(const _FILETIME& a_filetime) { return (static_cast(a_filetime.dwHighDateTime) << 32) + static_cast(a_filetime.dwLowDateTime); } ProcessorTime::ProcessorTime() { start(); } void ProcessorTime::start() { _FILETIME idle; _FILETIME kernel; _FILETIME user; user_value_ = ULONGLONG(); system_value_ = ULONGLONG(); GetSystemTimes(&idle, &kernel, &user); start_idle_value_ = filetime_in_100nanoseconds(idle); start_system_value_ = filetime_in_100nanoseconds(kernel); start_user_value_ = filetime_in_100nanoseconds(user); } void ProcessorTime::stop() { _FILETIME idle; _FILETIME kernel; _FILETIME user; GetSystemTimes(&idle, &kernel, &user); const ULONGLONG stop_idle_value = filetime_in_100nanoseconds(idle); const ULONGLONG stop_system_value = filetime_in_100nanoseconds(kernel); const ULONGLONG stop_user_value = filetime_in_100nanoseconds(user); system_value_ = stop_system_value - start_system_value_ - (stop_idle_value - start_idle_value_); user_value_ = stop_user_value - start_user_value_; start_idle_value_ = stop_idle_value; start_system_value_ = stop_system_value; start_user_value_ = stop_user_value; } void ProcessorTime::restart() { _FILETIME idle; _FILETIME kernel; _FILETIME user; GetSystemTimes(&idle, &kernel, &user); start_idle_value_ = filetime_in_100nanoseconds(idle); start_system_value_ = filetime_in_100nanoseconds(kernel); start_user_value_ = filetime_in_100nanoseconds(user); } double UserTime::value() const { return user_value_ / 1.0E7; } double SystemTime::value() const { return system_value_ / 1.0E7; } #elif defined(HAVE_SYS_TIMES_H) ProcessorTime::ProcessorTime() { start(); } void ProcessorTime::start() { user_value_ = clock_t(); system_value_ = clock_t(); times(&start_); stop_.tms_utime = start_.tms_utime; stop_.tms_stime = start_.tms_stime; } void ProcessorTime::stop() { times(&stop_); user_value_ = stop_.tms_utime - start_.tms_utime; system_value_ = stop_.tms_stime - start_.tms_stime; start_.tms_utime = stop_.tms_utime; start_.tms_stime = stop_.tms_stime; } void ProcessorTime::restart() { times(&start_); stop_.tms_utime = start_.tms_utime; stop_.tms_stime = start_.tms_stime; } double UserTime::value() const { return clock_in_seconds(user_value_); } double SystemTime::value() const { return clock_in_seconds(system_value_); } #else double UserTime::value() const { return 0.0; } double SystemTime::value() const { return 0.0; } #endif } // namespace timer enblend-enfuse-4.2/src/blend.h0000644000175000017500000001021612641706002013214 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __BLEND_H__ #define __BLEND_H__ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "fixmath.h" namespace enblend { /** Functor for blending a black and white pyramid level using a mask * pyramid level. */ template class CartesianBlendFunctor { public: CartesianBlendFunctor(MaskPixelType w) : white(vigra::NumericTraits::toRealPromote(w)) {} template ImagePixelType operator()(const MaskPixelType& maskP, const ImagePixelType& wP, const ImagePixelType& bP) const { typedef typename vigra::NumericTraits::RealPromote RealImagePixelType; // Convert mask pixel to blend coefficient in range [0.0, 1.0]. double whiteCoeff = vigra::NumericTraits::toRealPromote(maskP) / white; // Sometimes masked image data is invalid. For floating point samples // this includes possible NaN's in the data. In that case, computing // the output sample will result in a NaN output if the weight on that // pixel is 0 (since 0*NaN = NaN ) // Handle this by explicitly ignoring fully masked pixels if (whiteCoeff >= 1.0) { return wP; } if (whiteCoeff <= 0.0) { return bP; } const double blackCoeff = 1.0 - whiteCoeff; RealImagePixelType rwP = vigra::NumericTraits::toRealPromote(wP); RealImagePixelType rbP = vigra::NumericTraits::toRealPromote(bP); RealImagePixelType blendP = (whiteCoeff * rwP) + (blackCoeff * rbP); return vigra::NumericTraits::fromRealPromote(blendP); } protected: double white; }; /** Blend black and white pyramids using mask pyramid. */ template void blend(std::vector* maskGP, std::vector* whiteLP, std::vector* blackLP, typename MaskPyramidType::value_type maskPyramidWhiteValue) { if (Verbose >= VERBOSE_BLEND_MESSAGES) { std::cerr << command << ": info: blending layers: "; std::cerr.flush(); } #ifdef OPENMP omp::scoped_nested(true); omp::scoped_dynamic(true); #pragma omp parallel { #pragma omp single nowait { #endif for (unsigned int layer = 0; layer < maskGP->size(); layer++) { if (Verbose >= VERBOSE_BLEND_MESSAGES) { std::cerr << " l" << layer; std::cerr.flush(); } vigra::omp::combineThreeImages(srcImageRange(*((*maskGP)[layer])), srcImage(*((*whiteLP)[layer])), srcImage(*((*blackLP)[layer])), destImage(*((*blackLP)[layer])), CartesianBlendFunctor(maskPyramidWhiteValue)); } #ifdef OPENMP } // omp single } // omp parallel #endif if (Verbose >= VERBOSE_BLEND_MESSAGES) { std::cerr << std::endl; } } } // namespace enblend #endif /* __BLEND_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/fixmath.h0000644000175000017500000022144412673273713013614 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FIXMATH_H_INCLUDED_ #define FIXMATH_H_INCLUDED_ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include "mersenne.h" #include "minimizer.h" #include "muopt.h" #include "parameter.h" #define XYZ_SCALE 100.0 namespace enblend { static inline double wrap_cyclically(double x, double modulus) { while (x < 0.0) { x += modulus; } return fmod(x, modulus); } static inline double limit(double x, double lower_limit, double upper_limit) { if (EXPECT_RESULT(std::isnan(x), false)) { throw std::range_error("limit: not a number"); } return std::min(std::max(lower_limit, x), upper_limit); } static inline void jch_to_rgb(const cmsJCh* jch, double* rgb) { cmsCIEXYZ scaled_xyz; cmsCIECAM02Reverse(CIECAMTransform, jch, &scaled_xyz); // xyz values *approximately* in range [0, 100] // scale xyz values to range [0, 1] const double xyz[] = { scaled_xyz.X / XYZ_SCALE, scaled_xyz.Y / XYZ_SCALE, scaled_xyz.Z / XYZ_SCALE }; cmsDoTransform(XYZToInputTransform, xyz, rgb, 1U); // rgb values *approximately* in range [0, 1] } // A functor for converting scalar pixel values to the number // representation used for pyramids. These are either fixed-point // integers or floating-point numbers. template class ConvertScalarToPyramidFunctor { typedef vigra::NumericTraits SrcTraits; typedef typename SrcTraits::isIntegral SrcIsIntegral; typedef vigra::NumericTraits PyramidTraits; typedef typename PyramidTraits::isIntegral PyramidIsIntegral; public: ConvertScalarToPyramidFunctor() : pyramid_scale(double(1U << PyramidFractionBits)) { #ifdef DEBUG_COLORSPACE_STATISTICS #ifdef OPENMP #pragma omp critical #endif std::cout << "+ ConvertScalarToPyramidFunctor::ConvertScalarToPyramidFunctor: " << (SrcIsIntegral().value ? "integral" : "floating-point") << " source => " << (PyramidIsIntegral().value? "integral" : "floating-point") << " pyramid\n"; #endif } PyramidPixelType operator()(const SrcPixelType& v) const { return doConvert(v, SrcIsIntegral(), PyramidIsIntegral()); } protected: // Convert an integral pixel type to an integral pyramid value type. PyramidPixelType doConvert(const SrcPixelType& v, vigra::VigraTrueType, vigra::VigraTrueType) const { return convertIntegerToFixedPoint(v); } // Convert an integral pixel type to a real pyramid value type. PyramidPixelType doConvert(const SrcPixelType& v, vigra::VigraTrueType, vigra::VigraFalseType) const { return SrcTraits::toRealPromote(v); } // Convert a real pixel type to an integral pyramid value type. PyramidPixelType doConvert(const SrcPixelType& v, vigra::VigraFalseType, vigra::VigraTrueType) const { return convertDoubleToFixedPoint(v); } // Convert a real pixel type to a real pyramid value type. PyramidPixelType doConvert(const SrcPixelType& v, vigra::VigraFalseType, vigra::VigraFalseType) const { // Convert real data using a log transform. These achieves // two purposes: // 1. During blending, even completely non-negative images // can result in negative pixels. A log transform // followed by the exp inverse guarantees all-positive // output. // 2. For HDR data, the log transform put the samples closer // to a perceptual space making the blending a little more // pleasing. Ideally, all blending should be done in a // strictly perceptually-linear space, such as Luv or Lab. // // See ConvertPyramidToScalarFunctor::doConvert for the // inverse transform. // // Check for non-positive values -- they should not be in the // input, but if they are we need to handle them or log will // return a NaN. // // v >= 0.0 ? 1.0 + log(v + 1.0) : 1.0 / (1.0 - v) return v >= 0.0 ? 1.0 + log1p(v) : 1.0 / (1.0 - v); } PyramidPixelType convertDoubleToFixedPoint(const double& v) const { // Shift v to get the appropriate number of fraction bits into // the integer part, then fromRealPromote this value into the // fixed-point type. return PyramidTraits::fromRealPromote(v * pyramid_scale); } PyramidPixelType convertIntegerToFixedPoint(const SrcPixelType& v) const { // Shift v left to move the decimal point and set the fraction // bits to zero. return static_cast(v) << PyramidFractionBits; } private: const double pyramid_scale; }; template class SpecializedConvertPyramidToScalarFunctor { SpecializedConvertPyramidToScalarFunctor() { NEVER_REACHED("generic class SpecializedConvertPyramidToScalarFunctor must not be used"); } }; // SpecializedConvertPyramidToScalarFunctor template class SpecializedConvertPyramidToScalarFunctor { typedef vigra::NumericTraits DestTraits; typedef typename DestTraits::isIntegral DestIsIntegral; typedef vigra::NumericTraits PyramidTraits; typedef typename PyramidTraits::isIntegral PyramidIsIntegral; public: SpecializedConvertPyramidToScalarFunctor() : half_m1((1U << (PyramidFractionBits - 1)) - 1U), quarter(1U << (PyramidFractionBits - 2)), three_quarter(3U << (PyramidFractionBits - 2)), unit(double(1U << PyramidFractionBits)) { static_assert(PyramidFractionBits >= 2, "not enough PyramidFractionBits to calculate shifts"); random_number_generator_.non_deterministic_seed(); } DestPixelType operator()(const PyramidPixelType& v) const { return doConvert(v, DestIsIntegral()); } protected: // Test time with floating-point dithering: 100.01 sec // Test time with integer dithering: 94.89 sec // // Convert an integral pyramid pixel to an integral image pixel. DestPixelType doConvert(const PyramidPixelType& v, vigra::VigraTrueType) const { const PyramidPixelType vShifted = v >> PyramidFractionBits; const PyramidPixelType vFraction = v & ((1U << PyramidFractionBits) - 1U); if (vFraction >= quarter && vFraction < three_quarter) { const PyramidPixelType random = (PyramidPixelType(random_number_generator_()) & half_m1) + quarter; if (random <= vFraction) { return DestPixelType(DestTraits::fromPromote(vShifted + 1)); } else { return DestPixelType(DestTraits::fromPromote(vShifted)); } } else if (vFraction >= quarter) { return DestPixelType(DestTraits::fromPromote(vShifted + 1)); } else { return DestPixelType(DestTraits::fromPromote(vShifted)); } } // Convert an integral pyramid pixel to a real image pixel. DestPixelType doConvert(const PyramidPixelType& v, vigra::VigraFalseType) const { return PyramidTraits::toRealPromote(v) / unit; } private: const PyramidPixelType half_m1; const PyramidPixelType quarter; const PyramidPixelType three_quarter; const double unit; mutable UniformMersenneTwister random_number_generator_; }; // SpecializedConvertPyramidToScalarFunctor template class SpecializedConvertPyramidToScalarFunctor { typedef vigra::NumericTraits DestTraits; typedef typename DestTraits::isIntegral DestIsIntegral; typedef vigra::NumericTraits PyramidTraits; public: SpecializedConvertPyramidToScalarFunctor() { random_number_generator_.non_deterministic_seed(); } DestPixelType operator()(const PyramidPixelType& v) const { return doConvert(v, DestIsIntegral()); } protected: // Convert a real pyramid pixel to an integral image pixel. DestPixelType doConvert(const PyramidPixelType& v, vigra::VigraTrueType) const { return DestTraits::fromRealPromote(dither(v)); } // Convert a real pyramid pixel to a real image pixel. DestPixelType doConvert(const PyramidPixelType& v, vigra::VigraFalseType) const { // Undo logarithmic/rational mapping that was done in building // the pyramid. See ConvertScalarToPyramidFunctor::doConvert // for the forward transformation. return v >= 1.0 ? expm1(v - 1.0) : 1.0 - 1.0 / v; } // Dithering is used to fool the eye into seeing gradients that are finer // than the precision of the pixel type. // This prevents the occurence of cleanly-bordered regions in the output where // the pixel values suddenly change from N to N+1. // Such regions are especially objectionable in the green channel of 8-bit images. double dither(const double& v) const { const double vFraction = v - floor(v); // Only dither values within a certain range of the rounding cutoff point. if (vFraction > 0.25 && vFraction <= 0.75) { if (vFraction - 0.25 >= 0.5 * random_number_generator_.get_uniform()) { return ceil(v); } else { return floor(v); } } return v; } private: mutable UniformMersenneTwister random_number_generator_; }; // SpecializedConvertPyramidToScalarFunctor template using ConvertPyramidToScalarFunctor = class SpecializedConvertPyramidToScalarFunctor ::ValueType>::is_integer, PyramidIntegerBits, PyramidFractionBits>; //////////////////////////////////////////////////////////////////////////////////////////////// // // Converters for color (three component aka "vector") pixels // //////////////////////////////////////////////////////////////////////////////////////////////// // // Trivial RGB wrapper for vector pixel types // template class ConvertVectorToPyramidFunctor { typedef typename SrcVectorType::value_type SrcComponentType; typedef typename PyramidVectorType::value_type PyramidComponentType; typedef ConvertScalarToPyramidFunctor ConvertFunctorType; public: ConvertVectorToPyramidFunctor() : converter() {} PyramidVectorType operator()(const SrcVectorType& v) const { return PyramidVectorType(converter(v.red()), converter(v.green()), converter(v.blue())); } protected: ConvertFunctorType converter; }; // // Trivial RGB wrapper for vector pixel types // template class ConvertPyramidToVectorFunctor { typedef typename DestVectorType::value_type DestComponentType; typedef typename PyramidVectorType::value_type PyramidComponentType; typedef ConvertPyramidToScalarFunctor ConvertFunctorType; public: ConvertPyramidToVectorFunctor() : converter() {} DestVectorType operator()(const PyramidVectorType& v) const { return DestVectorType(converter(v.red()), converter(v.green()), converter(v.blue())); } protected: ConvertFunctorType converter; }; // // Configuration of CIELAB and CIELUV forward and backward transforms // template class PyramidScale { enum { // Maximum value of the `L'-channel for both L*a*b* and L*u*v* // color spaces. MAXIMUM_LIGHTNESS = 100, // PYRAMID_HEADROOM_BITS is the number of bits we must reserve // when we scale to the fixed-point based representation // inside the pyramid. They buffer soft overflows, like // e.g. a lightness of 100.001 and they are required to hold // the result of an addition or subtraction. PYRAMID_HEADROOM_BITS = 2 }; // Vigra Manual | Our Findings // ============================================================================== // | // Lab | Lab / copy into pyramid // 0 <= L* <= 100 | 0 <= L* <= 100 // -86.1813 <= a* <= 98.2352 | -79.275 <= a* <= 93.547 // -107.862 <= b* <= 94.4758 | -112.033 <= b* <= 93.391 // | Lab / copy from pyramid // | 0 <= L* <= 108.539 // | -79.375 <= a* <= 91.281 // | -111.125 <= b* <= 182.562 // | // Luv | Luv / copy into pyramid // 0 <= L* <= 100 | 0 <= L* <= 100.001 // -83.077 <= u* <= 175.015 | -34.796 <= u* <= 155.726 // -134.101 <= v* <= 107.393 | -114.366 <= v* <= 109.423 // | Luv / copy from pyramid // | 0 <= L* <= 136.719 // | -37.703 <= u* <= 101.203 // | -115.094 <= v* <= 200.422 public: PyramidScale() : color_limit(parameter::as_double("lab-color-limit", 200.0)), pyramid_scale(double(1U << (PyramidIntegerBits - PYRAMID_HEADROOM_BITS))) { static_assert(PyramidIntegerBits >= PYRAMID_HEADROOM_BITS, "not enough PyramidIntegerBits to calculate `pyramid_scale' from shift"); #ifdef DEBUG_COLORSPACE_STATISTICS #ifdef OPENMP #pragma omp critical #endif std::cout << "+ PyramidScale::PyramidScale: PyramidIntegerBits = " << PyramidIntegerBits << ", PyramidFractionBits = " << PyramidFractionBits << " => pyramid-scale = " << pyramid_scale << "\n"; #endif // DEBUG_COLORSPACE_STATISTICS } double scale_lightness_for_pyramid(double a_lightness) const { const double scaled_lightness = pyramid_scale * a_lightness / static_cast(MAXIMUM_LIGHTNESS); const double result = std::round(scaled_lightness); #ifdef DEBUG_COLORSPACE_STATISTICS // Note: For we rescale color channels with respect to // `color_limit' and color channels as well as luminance ends // up in the same pyramid, we can check for overflow with the // same limit. if (result < 0.0 || result > 1.0 + color_limit) { #ifdef OPENMP #pragma omp critical #endif std::cout << "+ PyramidScale::scale_lightness_for_pyramid: out-of-range L = " << a_lightness << ", scaled = " << scaled_lightness << ", rounded = " << result << "\n"; } #endif // DEBUG_COLORSPACE_STATISTICS assert(result >= 0.0); return result; } double scale_color_difference_for_pyramid(double a_color_difference) const { const double scaled_color_difference = pyramid_scale * (color_limit + a_color_difference) / (2.0 * color_limit); const double result = std::round(scaled_color_difference); #ifdef DEBUG_COLORSPACE_STATISTICS if (std::abs(result) > color_limit) { #ifdef OPENMP #pragma omp critical #endif std::cout << "+ PyramidScale::scale_color_difference_for_pyramid: out-of-range a,b|u,v = " << a_color_difference << ", scaled = " << scaled_color_difference << ", rounded = " << result << "\n"; } #endif // DEBUG_COLORSPACE_STATISTICS assert(result >= -color_limit); return result; } double scale_lightness_of_pyramid(double a_lightness) const { return a_lightness * static_cast(MAXIMUM_LIGHTNESS) / pyramid_scale; } double scale_color_difference_of_pyramid(double a_color_difference) const { return a_color_difference * (2.0 * color_limit) / pyramid_scale - color_limit; } private: const double color_limit; const double pyramid_scale; }; #ifdef DEBUG_COLORSPACE_STATISTICS class TriplePeakHold { enum {n = 3}; public: TriplePeakHold() { for (int i = 0; i < n; ++i) { std::ostringstream s; s << '#' << (i + 1); labels_[i] = s.str(); } for (auto& p : peaks_) { p.first = std::numeric_limits::max(); p.second = std::numeric_limits::min(); } } TriplePeakHold(const std::string& label1, const std::string& label2, const std::string& label3) { labels_[0] = label1; labels_[1] = label2; labels_[2] = label3; for (auto& p : peaks_) { p.first = std::numeric_limits::max(); p.second = std::numeric_limits::min(); } } void update(double value1, double value2, double value3) { peaks_[0].first = std::min(peaks_[0].first, value1); peaks_[0].second = std::max(peaks_[0].second, value1); peaks_[1].first = std::min(peaks_[1].first, value2); peaks_[1].second = std::max(peaks_[1].second, value2); peaks_[2].first = std::min(peaks_[2].first, value3); peaks_[2].second = std::max(peaks_[2].second, value3); } std::string as_string(const std::string a_prefix = std::string()) const { std::ostringstream s; for (int i = 0; i < n; ++i) { s << a_prefix << peaks_[i].first << " <= " << labels_[i] << " <= " << peaks_[i].second << "\n"; } return s.str(); } private: std::array labels_; std::array, n> peaks_; }; #endif // DEBUG_COLORSPACE_STATISTICS // // Fixed point converter that uses ICC profile transformation and L*a*b* color space // template class ConvertVectorToLabPyramidFunctor : private PyramidScale { typedef PyramidScale Scale; typedef typename SrcVectorType::value_type SrcComponentType; typedef vigra::NumericTraits SrcTraits; typedef typename PyramidVectorType::value_type PyramidComponentType; typedef ConvertScalarToPyramidFunctor ConvertFunctorType; public: ConvertVectorToLabPyramidFunctor() : converter(), rgb_source_scale(1.0 / SrcTraits::toRealPromote(SrcTraits::max())) #ifdef DEBUG_COLORSPACE_STATISTICS , range("L", "a", "b") #endif // DEBUG_COLORSPACE_STATISTICS { #ifdef DEBUG_COLORSPACE_STATISTICS #ifdef OPENMP #pragma omp critical #endif std::cout << "+ ConvertVectorToLabPyramidFunctor::ConvertVectorToLabPyramidFunctor source range [" << static_cast(SrcTraits::min()) << ", " << static_cast(SrcTraits::max()) << "]\n" << "+ ConvertVectorToLabPyramidFunctor::ConvertVectorToLabPyramidFunctor: pyramid range [" << static_cast(vigra::NumericTraits::min()) << ", " << static_cast(vigra::NumericTraits::max()) << "]\n"; #endif // DEBUG_COLORSPACE_STATISTICS } #ifdef DEBUG_COLORSPACE_STATISTICS ~ConvertVectorToLabPyramidFunctor() { #ifdef OPENMP #pragma omp critical #endif std::cout << range.as_string("+ ConvertVectorToLabPyramidFunctor::~ConvertVectorToLabPyramidFunctor: ") << std::endl; } #endif // DEBUG_COLORSPACE_STATISTICS PyramidVectorType operator()(const SrcVectorType& v) const { const double rgb[] = { rgb_source_scale * SrcTraits::toRealPromote(v.red()), rgb_source_scale * SrcTraits::toRealPromote(v.green()), rgb_source_scale * SrcTraits::toRealPromote(v.blue()) }; cmsCIELab lab; cmsDoTransform(InputToLabTransform, rgb, &lab, 1U); #ifdef DEBUG_COLORSPACE_STATISTICS range.update(lab.L, lab.a, lab.b); #endif // DEBUG_COLORSPACE_STATISTICS return PyramidVectorType(converter(Scale::scale_lightness_for_pyramid(lab.L)), converter(Scale::scale_color_difference_for_pyramid(lab.a)), converter(Scale::scale_color_difference_for_pyramid(lab.b))); } protected: ConvertFunctorType converter; const double rgb_source_scale; #ifdef DEBUG_COLORSPACE_STATISTICS mutable TriplePeakHold range; #endif // DEBUG_COLORSPACE_STATISTICS }; // // Fixed point converter that uses ICC profile transformation and L*a*b* color space // template class ConvertLabPyramidToVectorFunctor : private PyramidScale { typedef PyramidScale Scale; typedef typename DestVectorType::value_type DestComponentType; typedef vigra::NumericTraits DestTraits; typedef typename PyramidVectorType::value_type PyramidComponentType; typedef ConvertPyramidToScalarFunctor ConvertFunctorType; public: ConvertLabPyramidToVectorFunctor() : converter(), rgb_dest_scale(DestTraits::toRealPromote(DestTraits::max())) #ifdef DEBUG_COLORSPACE_STATISTICS , range("L", "a", "b") #endif // DEBUG_COLORSPACE_STATISTICS { #ifdef DEBUG_COLORSPACE_STATISTICS #ifdef OPENMP #pragma omp critical #endif std::cout << "+ ConvertLabPyramidToVectorFunctor::ConvertLabPyramidToVectorFunctor: dest range [" << static_cast(DestTraits::min()) << ", " << static_cast(DestTraits::max()) << "]\n" << "+ ConvertLabPyramidToVectorFunctor::ConvertLabPyramidToVectorFunctor: pyramid range [" << static_cast(vigra::NumericTraits::min()) << ", " << static_cast(vigra::NumericTraits::max()) << "]\n"; #endif // DEBUG_COLORSPACE_STATISTICS } #ifdef DEBUG_COLORSPACE_STATISTICS ~ConvertLabPyramidToVectorFunctor() { #ifdef OPENMP #pragma omp critical #endif std::cout << range.as_string("+ ConvertLabPyramidToVectorFunctor::~ConvertLabPyramidToVectorFunctor: ") << std::endl; } #endif // DEBUG_COLORSPACE_STATISTICS DestVectorType operator()(const PyramidVectorType& v) const { const cmsCIELab lab = { Scale::scale_lightness_of_pyramid(converter(v.red())), Scale::scale_color_difference_of_pyramid(converter(v.green())), Scale::scale_color_difference_of_pyramid(converter(v.blue())) }; double rgb[3]; #ifdef DEBUG_COLORSPACE_STATISTICS range.update(lab.L, lab.a, lab.b); #endif // DEBUG_COLORSPACE_STATISTICS cmsDoTransform(LabToInputTransform, &lab, rgb, 1U); return DestVectorType(DestTraits::fromRealPromote(rgb_dest_scale * rgb[0]), DestTraits::fromRealPromote(rgb_dest_scale * rgb[1]), DestTraits::fromRealPromote(rgb_dest_scale * rgb[2])); } protected: ConvertFunctorType converter; const double rgb_dest_scale; #ifdef DEBUG_COLORSPACE_STATISTICS mutable TriplePeakHold range; #endif // DEBUG_COLORSPACE_STATISTICS }; // // Fixed point converter that uses ICC profile transformation and L*u*v* color space // template class ConvertVectorToLuvPyramidFunctor : private PyramidScale { typedef PyramidScale Scale; typedef typename SrcVectorType::value_type SrcComponentType; typedef vigra::NumericTraits SrcTraits; typedef typename PyramidVectorType::value_type PyramidComponentType; typedef ConvertScalarToPyramidFunctor ConvertFunctorType; typedef vigra::XYZ2LuvFunctor XYZ2LuvFunctor; public: ConvertVectorToLuvPyramidFunctor() : converter(), rgb_source_scale(1.0 / SrcTraits::toRealPromote(SrcTraits::max())) #ifdef DEBUG_COLORSPACE_STATISTICS , range("L", "u", "v") #endif // DEBUG_COLORSPACE_STATISTICS { #ifdef DEBUG_COLORSPACE_STATISTICS #ifdef OPENMP #pragma omp critical #endif std::cout << "+ ConvertVectorToLuvPyramidFunctor::ConvertVectorToLuvPyramidFunctor source range [" << static_cast(SrcTraits::min()) << ", " << static_cast(SrcTraits::max()) << "]\n" << "+ ConvertVectorToLuvPyramidFunctor::ConvertVectorToLuvPyramidFunctor: pyramid range [" << static_cast(vigra::NumericTraits::min()) << ", " << static_cast(vigra::NumericTraits::max()) << "]\n"; #endif // DEBUG_COLORSPACE_STATISTICS } #ifdef DEBUG_COLORSPACE_STATISTICS ~ConvertVectorToLuvPyramidFunctor() { #ifdef OPENMP #pragma omp critical #endif std::cout << range.as_string("+ ConvertVectorToLuvPyramidFunctor::~ConvertVectorToLuvPyramidFunctor: ") << std::endl; } #endif // DEBUG_COLORSPACE_STATISTICS PyramidVectorType operator()(const SrcVectorType& v) const { const double rgb[] = { rgb_source_scale * SrcTraits::toRealPromote(v.red()), rgb_source_scale * SrcTraits::toRealPromote(v.green()), rgb_source_scale * SrcTraits::toRealPromote(v.blue()) }; XYZ2LuvFunctor::argument_type xyz; cmsDoTransform(InputToXYZTransform, rgb, &xyz[0], 1U); const XYZ2LuvFunctor::result_type luv {xyz2luv(xyz)}; #ifdef DEBUG_COLORSPACE_STATISTICS range.update(luv[0], luv[1], luv[2]); #endif // DEBUG_COLORSPACE_STATISTICS return PyramidVectorType(converter(Scale::scale_lightness_for_pyramid(luv[0])), converter(Scale::scale_color_difference_for_pyramid(luv[1])), converter(Scale::scale_color_difference_for_pyramid(luv[2]))); } protected: XYZ2LuvFunctor xyz2luv; ConvertFunctorType converter; const double rgb_source_scale; #ifdef DEBUG_COLORSPACE_STATISTICS mutable TriplePeakHold range; #endif // DEBUG_COLORSPACE_STATISTICS }; // // Fixed point converter that uses ICC profile transformation and L*u*v* color space // template class ConvertLuvPyramidToVectorFunctor : private PyramidScale { typedef PyramidScale Scale; typedef typename DestVectorType::value_type DestComponentType; typedef vigra::NumericTraits DestTraits; typedef typename PyramidVectorType::value_type PyramidComponentType; typedef ConvertPyramidToScalarFunctor ConvertFunctorType; typedef vigra::Luv2XYZFunctor Luv2XYZFunctor; public: ConvertLuvPyramidToVectorFunctor() : converter(), rgb_dest_scale(DestTraits::toRealPromote(DestTraits::max())) #ifdef DEBUG_COLORSPACE_STATISTICS , range("L", "u", "v") #endif // DEBUG_COLORSPACE_STATISTICS { #ifdef DEBUG_COLORSPACE_STATISTICS #ifdef OPENMP #pragma omp critical #endif std::cout << "+ ConvertLuvPyramidToVectorFunctor::ConvertLuvPyramidToVectorFunctor: dest range [" << static_cast(DestTraits::min()) << ", " << static_cast(DestTraits::max()) << "]\n" << "+ ConvertLuvPyramidToVectorFunctor::ConvertLuvPyramidToVectorFunctor: pyramid range [" << static_cast(vigra::NumericTraits::min()) << ", " << static_cast(vigra::NumericTraits::max()) << "]\n"; #endif // DEBUG_COLORSPACE_STATISTICS } #ifdef DEBUG_COLORSPACE_STATISTICS ~ConvertLuvPyramidToVectorFunctor() { #ifdef OPENMP #pragma omp critical #endif std::cout << range.as_string("+ ConvertLuvPyramidToVectorFunctor::~ConvertLuvPyramidToVectorFunctor: ") << std::endl; } #endif // DEBUG_COLORSPACE_STATISTICS DestVectorType operator()(const PyramidVectorType& v) const { const Luv2XYZFunctor::value_type luv { Scale::scale_lightness_of_pyramid(converter(v.red())), Scale::scale_color_difference_of_pyramid(converter(v.green())), Scale::scale_color_difference_of_pyramid(converter(v.blue())) }; #ifdef DEBUG_COLORSPACE_STATISTICS range.update(luv[0], luv[1], luv[2]); #endif // DEBUG_COLORSPACE_STATISTICS const Luv2XYZFunctor::result_type xyz {luv2xyz(luv)}; double rgb[3]; cmsDoTransform(XYZToInputTransform, &xyz[0], rgb, 1U); return DestVectorType(DestTraits::fromRealPromote(rgb_dest_scale * rgb[0]), DestTraits::fromRealPromote(rgb_dest_scale * rgb[1]), DestTraits::fromRealPromote(rgb_dest_scale * rgb[2])); } protected: Luv2XYZFunctor luv2xyz; ConvertFunctorType converter; const double rgb_dest_scale; #ifdef DEBUG_COLORSPACE_STATISTICS mutable TriplePeakHold range; #endif // DEBUG_COLORSPACE_STATISTICS }; template class PyramidScaleJCh { public: enum { MAXIMUM_LIGHTNESS = 100, // J MAXIMUM_CHROMA = 120, // C MAXIMUM_HUE = 360 // h }; PyramidScaleJCh() : pyramid_scale(double(1U << (PyramidIntegerBits - 1 - 7))) { static_assert(PyramidIntegerBits >= 8, "not enough PyramidIntegerBits to get `pyramid_scale' from shift"); #ifdef DEBUG_COLORSPACE_STATISTICS #ifdef OPENMP #pragma omp critical #endif std::cout << "+ PyramidScaleJCh::PyramidScaleJCh: PyramidIntegerBits = " << PyramidIntegerBits << ", PyramidFractionBits = " << PyramidFractionBits << " => pyramid-scale = " << pyramid_scale << "\n"; #endif // DEBUG_COLORSPACE_STATISTICS } double scale_lightness_for_pyramid(double a_lightness) const { return a_lightness * pyramid_scale; } double scale_chroma_hue_x_for_pyramid(double a_chroma, double a_hue_angle) const { return a_chroma * sin(a_hue_angle) * pyramid_scale; } double scale_chroma_hue_y_for_pyramid(double a_chroma, double a_hue_angle) const { return a_chroma * cos(a_hue_angle) * pyramid_scale; } double scale_lightness_of_pyramid(double a_scaled_lightness) const { return a_scaled_lightness / pyramid_scale; } double scale_chroma_of_pyramid(double a_scaled_x, double a_scaled_y) const { return hypot(a_scaled_x / pyramid_scale, a_scaled_y / pyramid_scale); } double scale_hue_of_pyramid(double a_scaled_x, double a_scaled_y) const { return wrap_cyclically(degree_of_radian(atan2(a_scaled_x / pyramid_scale, a_scaled_y / pyramid_scale)), MAXIMUM_HUE); } private: double degree_of_radian(double x) const {return x * (180.0 / M_PI);} const double pyramid_scale; }; // // Fixed point converter that uses ICC profile transformation and JCh color space // template class ConvertVectorToJCHPyramidFunctor : private PyramidScaleJCh { typedef PyramidScaleJCh Scale; typedef typename SrcVectorType::value_type SrcComponentType; typedef vigra::NumericTraits SrcTraits; typedef typename PyramidVectorType::value_type PyramidComponentType; typedef ConvertScalarToPyramidFunctor ConvertFunctorType; public: ConvertVectorToJCHPyramidFunctor() : converter(), rgb_source_scale(1.0 / SrcTraits::toRealPromote(SrcTraits::max())) {} PyramidVectorType operator()(const SrcVectorType& v) const { // rgb values must be in range [0, 1] const double rgb[] = { rgb_source_scale * SrcTraits::toRealPromote(v.red()), rgb_source_scale * SrcTraits::toRealPromote(v.green()), rgb_source_scale * SrcTraits::toRealPromote(v.blue()) }; cmsJCh jch; rgb_to_jch(rgb, &jch); const double theta = radian_of_degree(jch.h); return PyramidVectorType(converter(Scale::scale_lightness_for_pyramid(jch.J)), converter(Scale::scale_chroma_hue_x_for_pyramid(jch.C, theta)), converter(Scale::scale_chroma_hue_y_for_pyramid(jch.C, theta))); } protected: double radian_of_degree(double x) const { return x * (M_PI / 180.0); } void rgb_to_jch(const double* rgb, cmsJCh* jch) const { double xyz[3]; cmsDoTransform(InputToXYZTransform, rgb, xyz, 1U); const cmsCIEXYZ scaled_xyz = {XYZ_SCALE * xyz[0], XYZ_SCALE * xyz[1], XYZ_SCALE * xyz[2]}; cmsJCh jch_unlimited; cmsCIECAM02Forward(CIECAMTransform, &scaled_xyz, &jch_unlimited); jch->J = EXPECT_RESULT(std::isnan(jch_unlimited.J), false) ? 0.0 : jch_unlimited.J; jch->C = EXPECT_RESULT(std::isnan(jch_unlimited.C), false) ? 0.0 : jch_unlimited.C; jch->h = wrap_cyclically(jch_unlimited.h, Scale::MAXIMUM_HUE); } ConvertFunctorType converter; const double rgb_source_scale; }; namespace ciecam_detail { template static inline void limit_sequence(forward_iterator first, forward_iterator last, double lower_limit, double upper_limit) { while (first != last) { *first = limit(*first, lower_limit, upper_limit); ++first; } } static inline double uniform_random(unsigned* seed) { return static_cast(enblend::rand_r(seed)) / static_cast(RAND_MAX); } static inline bool bracket_minimum(const gsl_function& cost, double& x_initial, double x_lower, double x_upper, unsigned maximum_tries) { const double y_minimum_bound = std::min(cost.function(x_lower, cost.params), cost.function(x_upper, cost.params)); double y_initial = cost.function(x_initial, cost.params); if (y_initial < y_minimum_bound) { return true; } unsigned i = 0U; const double lower = std::max(0.001, 1.001 * x_lower); const double upper = 0.999 * x_upper; unsigned seed = 1000003U; // fixed seed for reproducibility while (y_initial >= y_minimum_bound && i < maximum_tries) { x_initial = uniform_random(&seed) * (upper - lower) + lower; y_initial = cost.function(x_initial, cost.params); ++i; } return i < maximum_tries; } static inline int alternating_power_spacing(int i, int n, double a, double b, double c, double p) { const bool is_even_n = n % 2 == 0; const double left_unit_stride = 1.0 / static_cast(n - (is_even_n ? 1 : 2)); const double right_unit_stride = 1.0 / static_cast(n - (is_even_n ? 2 : 1)); const double left_width = c - a; const double right_width = b - c; const double x = static_cast(i); double y = c; if (i % 2 == 1) // 1, 3, 5, ... { y -= left_width * std::pow(x * left_unit_stride, 1.0 / p); } else // 0, 2, 4, 6, ... { y += right_width * std::pow(x * right_unit_stride, p); } return y; } struct extra_minimizer_parameter { explicit extra_minimizer_parameter(const cmsJCh& out_of_box_jch) : jch(out_of_box_jch) { double rgb[3]; jch_to_rgb(&jch, rgb); cmsDoTransform(InputToLabTransform, rgb, &bad_lab, 1); } cmsJCh jch; cmsCIELab bad_lab; }; inline double delta_e_of_lab_and_rgb(const cmsCIELab* lab, const double* rgb) { cmsCIELab lab_of_rgb; cmsDoTransform(InputToLabTransform, rgb, &lab_of_rgb, 1); return cmsCMCdeltaE(lab, &lab_of_rgb, 2.0, 1.0); } inline double out_of_box_penalty(const double* rgb) { const double infinite_badness = 10000.0; double result = 0.0; for (int i = 0; i < 3; ++i) { if (rgb[i] > 1.0) { result += rgb[i] * infinite_badness; } else if (rgb[i] < 0.0) { result += (1.0 - rgb[i]) * infinite_badness; } } return result; } inline double delta_e_cost(const cmsJCh* jch, const extra_minimizer_parameter* parameter) { double rgb[3]; jch_to_rgb(jch, rgb); return delta_e_of_lab_and_rgb(¶meter->bad_lab, rgb) + out_of_box_penalty(rgb); } double delta_e_min_cost(double luminance, void* data) { const extra_minimizer_parameter* parameter = static_cast(data); const cmsJCh jch = {luminance, parameter->jch.C, parameter->jch.h}; return delta_e_cost(&jch, parameter); } double delta_e_multimin_cost(const gsl_vector* x, void* data) { const extra_minimizer_parameter* parameter = static_cast(data); const cmsJCh jch = {gsl_vector_get(x, 0), gsl_vector_get(x, 1), parameter->jch.h}; return delta_e_cost(&jch, parameter); } void show_jch_rgb(const std::string& label, const cmsJCh* jch) { double rgb[3]; jch_to_rgb(jch, rgb); std::cout << label << " J = " << jch->J << ", C = " << jch->C << ", h = " << jch->h << "\n" << label << " RGB = (" << rgb[0] << ", " << rgb[1] << ", " << rgb[2] << ")" << std::endl; } } // namespace ciecam_detail // // Fixed point converter that uses ICC profile transformation and JCh color space // template class ConvertJCHPyramidToVectorFunctor : private PyramidScaleJCh { typedef PyramidScaleJCh Scale; typedef typename DestVectorType::value_type DestComponentType; typedef vigra::NumericTraits DestTraits; typedef typename PyramidVectorType::value_type PyramidComponentType; typedef ConvertPyramidToScalarFunctor ConvertFunctorType; public: ConvertJCHPyramidToVectorFunctor() : converter(), rgb_dest_scale(DestTraits::toRealPromote(DestTraits::max())), // Parameters for highlight optimizer only highlight_lightness_guess_1d_factor(limit(parameter::as_double("highlight-recovery-lightness-guess-factor", 0.975), 0.25, 4.0)), highlight_lightness_guess_1d_offset(parameter::as_double("highlight-recovery-lightness-guess-offset", 0.0)), maximum_highlight_iterations(limit(parameter::as_unsigned("highlight-recovery-maximum-iterations", 100U), 10U, 1000U)), maximum_highlight_bracket_tries(limit(parameter::as_unsigned("highlight-recovery-bracket-maximum-tries", 1000U), 10U, 1000000U)), highlight_simplex_lightness_step_length(limit(parameter::as_double("highlight-recovery-lightness-step-length", 12.5), 1.0 / 65536.0, 100.0)), highlight_simplex_chroma_step_length(limit(parameter::as_double("highlight-recovery-chroma-step-length", 6.25), 1.0 / 65536.0, 120.0)), highlight_iterations_per_leg(limit(parameter::as_unsigned("highlight-recovery-iterations-per-leg", 50U), 5U, 500U)), maximum_highlight_leg(limit(parameter::as_unsigned("highlight-recovery-maximum-legs", 10U), 1U, 100U)), shadow_disguised_as_highlight_j(limit(parameter::as_double("shadow-disguised-as-highlight-lightness", 1.0), 0.0001, 10.0)), // Parameters for shadow optimizer only shadow_lightness_lightness_guess_factor(parameter::as_double("shadow-recovery-lightness-lightness-guess-factor", 1.24)), shadow_lightness_chroma_guess_factor(parameter::as_double("shadow-recovery-lightness-chroma-guess-factor", -0.136)), shadow_lightness_guess_offset(parameter::as_double("shadow-recovery-lightness-guess-offset", 0.0)), shadow_chroma_lightness_guess_factor(parameter::as_double("shadow-recovery-chroma-lightness-guess-factor", -0.604)), shadow_chroma_chroma_guess_factor(parameter::as_double("shadow-recovery-chroma-chroma-guess-factor", 1.33)), shadow_chroma_guess_offset(parameter::as_double("shadow-recovery-chroma-guess-offset", 0.0)), shadow_simplex_lightness_step_length(limit(parameter::as_double("shadow-recovery-lightness-step-length", 0.625), 1.0 / 65536.0, 100.0)), shadow_simplex_chroma_step_length(limit(parameter::as_double("shadow-recovery-chroma-step-length", 1.25), 1.0 / 65536.0, 120.0)), shadow_iterations_per_leg(limit(parameter::as_unsigned("shadow-recovery-iterations-per-leg", 40U), 4U, 400U)), maximum_shadow_leg(limit(parameter::as_unsigned("shadow-recovery-maximum-legs", 5U), 1U, 50U)), maximum_multistart_tries(limit(parameter::as_unsigned("shadow-recovery-maximum_tries", 20U), 1U, 500U)), // Parameters for both optimizers // Desired error limits: LoFi: 0.5/2^8, HiFi: 0.5/2^16, Super-HiFi: 0.5/2^24 optimizer_error(limit(parameter::as_double("ciecam-optimizer-error", 0.5 / 65536.0), 0.5 / 16777216.0, 1.0)), // Delta-E goals: LoFi: 1.0, HiFi: 0.5, Super-HiFi: 0.0 optimizer_goal(limit(parameter::as_double("ciecam-optimizer-deltae-goal", 0.5), 0.0, 10.0)) {} double highlight_lightness_guess_1d(const cmsJCh& jch) const { return std::min( // heuristic function with fitted parameter highlight_lightness_guess_1d_factor * jch.J + highlight_lightness_guess_1d_offset, 0.995 * Scale::MAXIMUM_LIGHTNESS); // backstop such that our guess is less than the maximum } double highlight_lightness_guess_2d(const cmsJCh& jch) const { return std::min(0.99609375 * Scale::MAXIMUM_LIGHTNESS, jch.J); } double highlight_chroma_guess_2d(const cmsJCh& jch) const { return std::min(0.99609375 * Scale::MAXIMUM_CHROMA, jch.C); } double shadow_lightness_guess_2d(const cmsJCh& jch) const { return std::max(shadow_lightness_lightness_guess_factor * jch.J + shadow_lightness_chroma_guess_factor * jch.C + shadow_lightness_guess_offset, 0.0); } double shadow_chroma_guess_2d(const cmsJCh& jch) const { return std::max(shadow_chroma_lightness_guess_factor * jch.J + shadow_chroma_chroma_guess_factor * jch.C + shadow_chroma_guess_offset, 0.0); } double optimize_1d(cmsJCh initial_jch, double initial_lightness, unsigned maximum_iterations, cmsJCh& final_jch) const { ciecam_detail::extra_minimizer_parameter extra(initial_jch); gsl_function cost = {ciecam_detail::delta_e_min_cost, &extra}; GoldenSectionMinimizer1D optimizer(cost, initial_lightness, 0.0, std::max(static_cast(Scale::MAXIMUM_LIGHTNESS), initial_jch.J)); optimizer.set_absolute_error(optimizer_error)-> set_goal(optimizer_goal)-> set_maximum_number_of_iterations(maximum_iterations); optimizer.run(); final_jch.J = optimizer.x_minimum(); #ifdef DEBUG_OPTIMIZE_1D_STATISTICS #ifdef OPENMP #pragma omp critical #endif { ciecam_detail::show_jch_rgb("+ optimize_1d: initial", &initial_jch); std::cout << "+ optimize_1d: reached after " << optimizer.number_of_iterations() << " iterations\n" << "+ optimize_1d: delta-E = " << optimizer.f_minimum() << "\n"; ciecam_detail::show_jch_rgb("+ optimize_1d: final", &final_jch); } #endif return optimizer.f_minimum(); } double optimize_2d(cmsJCh initial_jch, double initial_lightness, double initial_chroma, double initial_lightness_step_length, double initial_chroma_step_length, unsigned maximum_leg, unsigned iterations_per_leg, cmsJCh& final_jch) const { ciecam_detail::extra_minimizer_parameter extra(initial_jch); gsl_multimin_function cost = {ciecam_detail::delta_e_multimin_cost, 2U, &extra}; const MinimizerMultiDimensionSimplex::array_type initial = { initial_lightness, initial_chroma }; MinimizerMultiDimensionSimplex::array_type step = { initial_lightness_step_length, initial_chroma_step_length }; MinimizerMultiDimensionSimplex2Randomized optimizer(cost, initial, step); optimizer.set_absolute_error(optimizer_error)->set_goal(optimizer_goal); for (unsigned leg = 1U; leg <= maximum_leg; ++leg) { optimizer.set_maximum_number_of_iterations(leg * iterations_per_leg); optimizer.run(); if (optimizer.has_reached_goal()) { break; } step[0] = optimizer.characteristic_size(); step[1] = optimizer.characteristic_size(); optimizer.set_step_sizes(step); } MinimizerMultiDimensionSimplex::array_type minimum_parameter(2U); optimizer.x_minimum(minimum_parameter.begin()); final_jch = {minimum_parameter[0], minimum_parameter[1], initial_jch.h}; return optimizer.f_minimum(); } void multistart_optimize_2d(const cmsJCh* initial_jch, double* rgb) const { const double guessed_j = shadow_lightness_guess_2d(*initial_jch); const double guessed_c = shadow_chroma_guess_2d(*initial_jch); double best_deltae = std::numeric_limits::infinity(); cmsJCh best_jch = *initial_jch; unsigned n = 0U; while (n < maximum_multistart_tries) { cmsJCh jch; const double opt_deltae = optimize_2d(*initial_jch, ciecam_detail::alternating_power_spacing(n, maximum_multistart_tries, 0.0, Scale::MAXIMUM_LIGHTNESS, guessed_j, 2.0), guessed_c, shadow_simplex_lightness_step_length, shadow_simplex_chroma_step_length, maximum_shadow_leg, shadow_iterations_per_leg, jch); if (opt_deltae < best_deltae) { best_deltae = opt_deltae; best_jch = jch; } if (opt_deltae <= optimizer_goal) { best_deltae = opt_deltae; best_jch = jch; break; } ++n; } jch_to_rgb(&best_jch, rgb); #ifdef DEBUG_SHADOW_HIGHLIGHT_STATISTICS if (best_deltae > optimizer_goal) { #ifdef OPENMP #pragma omp critical #endif std::cout << "\n" << "+ multistart_optimize_2d: recovery failure: deltaE = " << best_deltae << " after " << n + 1U << " iteration[s]\n"; ciecam_detail::show_jch_rgb("+ multistart_optimize_2d: initial", initial_jch); ciecam_detail::show_jch_rgb("+ multistart_optimize_2d: final", &best_jch); } #endif } void flexible_optimize_1d_2d(const cmsJCh* jch, double* rgb) const { double guessed_j = highlight_lightness_guess_1d(*jch); ciecam_detail::extra_minimizer_parameter extra(*jch); gsl_function cost = {ciecam_detail::delta_e_min_cost, &extra}; cmsJCh opt_jch = *jch; double delta_e_1d = 0.0; double delta_e_2d __attribute__((unused)) = 0.0; if (EXPECT_RESULT(ciecam_detail::bracket_minimum(cost, guessed_j, 0.0, std::max(static_cast(Scale::MAXIMUM_LIGHTNESS), jch->J), maximum_highlight_bracket_tries), true)) { delta_e_1d = optimize_1d(*jch, guessed_j, maximum_highlight_iterations, opt_jch); if (delta_e_1d > optimizer_goal) { #ifdef DEBUG_HIGHLIGHT_FALLBACK_STATISTICS #ifdef OPENMP #pragma omp critical #endif std::cout << "+ flexible_optimize_1d_2d: falling back from J-optimizer to (J, C)-optimizer for J = " << jch->J << ", {C = " << jch->C << ", h = " << jch->h << "}\n" << "+ 1d opt J = " << opt_jch.J << " and 1d delta-E = " << delta_e_1d << std::endl; #endif delta_e_2d = optimize_2d(opt_jch, highlight_lightness_guess_2d(opt_jch), highlight_chroma_guess_2d(opt_jch), highlight_simplex_lightness_step_length, highlight_simplex_chroma_step_length, maximum_highlight_leg, highlight_iterations_per_leg, opt_jch); } } else { delta_e_2d = optimize_2d(*jch, highlight_lightness_guess_2d(*jch), highlight_chroma_guess_2d(*jch), highlight_simplex_lightness_step_length, highlight_simplex_chroma_step_length, maximum_highlight_leg, highlight_iterations_per_leg, opt_jch); } jch_to_rgb(&opt_jch, rgb); #ifdef DEBUG_SHADOW_HIGHLIGHT_STATISTICS if (delta_e_1d > optimizer_goal && delta_e_2d > optimizer_goal) { #ifdef OPENMP #pragma omp critical #endif { std::cout << "\n" << "+ flexible_optimize_1d_2d: failed to reach optimizer goal " << optimizer_goal << " -- only achived deltaE{1d} = " << delta_e_1d << ", deltaE{2d} = " << delta_e_2d << "\n"; ciecam_detail::show_jch_rgb("+ flexible_optimize_1d_2d: initial", jch); ciecam_detail::show_jch_rgb("+ flexible_optimize_1d_2d: final", &opt_jch); } } #endif } DestVectorType operator()(const PyramidVectorType& v) const { const double j = converter(v.red()); const double ch_x = converter(v.green()); const double ch_y = converter(v.blue()); const cmsJCh jch = { Scale::scale_lightness_of_pyramid(j), Scale::scale_chroma_of_pyramid(ch_x, ch_y), Scale::scale_hue_of_pyramid(ch_x, ch_y) }; if (jch.J <= 0.0) { // Lasciate ogne speranza, voi ch'intrate. return DestVectorType(0, 0, 0); } double rgb[3]; jch_to_rgb(&jch, rgb); // Implementation Notes // // New LittleCMS versions use "open color space" arithmetics, which means color // coordinates can end up outside their domains, e.g. JCh cylinder or RGB cube. We just // let LittleCMS chug along freewheeling as long as possible. Right here, we must take // care of out-of-cube RGB values, because the array `rgb[3]' ends up as pixel in the // user's image. We exert great care on the renegade pixels to preserve as much // information as possible; for example we *always* preserve the color component (h). // // (1) Overflow - at least one component is larger than one. // Function: flexible_optimize_1d_2d() // First try to find a visually similar pixel with different luminance (J). If no // pixel is close enough extend the search to luminance-saturation space (J, C). // (2) Underflow - at least one component less than zero. // Function: multistart_optimize_2d() // Search luminance-saturation space (J, C) for a visually similar pixel using many // different initial luminance (J) values. // // Bear in mind that cases (1) and (2) are *not* disjoint! // // (3) Low-J pixels and the special cases rgb[i] == 0.0, i = 0, 1, 2. // Some, but not all, RGB pixels that overflow, i.e. case (1), underflow, i.e. case // (2), or have one or more components equal to zero are in fact dim shadows and // neither bright highlights nor fancy sparkling green -- and infrequently -- // blue-ish dots. We call them "shadows disguised as highlights". // // These kind of deceivers *cannot* be roped in with our optimization strategies // because their RGB values diverge more and more the closer we get to reasonable // luminances. The reason is that we always assume a non-zero saturation (C), the // JCh model wants to compensate the low luminance, and the RGB components go // haywire. We solve the problem by expunging the saturation before launching the // shadow optimizer. if (rgb[0] > 1.0 || rgb[1] > 1.0 || rgb[2] > 1.0) { if (jch.J <= shadow_disguised_as_highlight_j) { const cmsJCh ich {jch.J, 0.0, jch.h}; multistart_optimize_2d(&ich, rgb); } else { flexible_optimize_1d_2d(&jch, rgb); } } else if (rgb[0] <= 0.0 || rgb[1] <= 0.0 || rgb[2] <= 0.0) { if (jch.J <= shadow_disguised_as_highlight_j) { const cmsJCh ich {jch.J, 0.0, jch.h}; multistart_optimize_2d(&ich, rgb); } else { multistart_optimize_2d(&jch, rgb); } } #ifdef DEBUG_STUBBORN_SHADOW_HIGHLIGHT if (rgb[0] > 1.0 || rgb[1] > 1.0 || rgb[2] > 1.0) { #ifdef OPENMP #pragma omp critical #endif { std::cout << "\n"; ciecam_detail::show_jch_rgb("+ stubborn highlight:", &jch); } } if (rgb[0] < 0.0 || rgb[1] < 0.0 || rgb[2] < 0.0) { #ifdef OPENMP #pragma omp critical #endif { std::cout << "\n"; ciecam_detail::show_jch_rgb("+ stubborn shadow:", &jch); } } #endif ciecam_detail::limit_sequence(rgb, rgb + 3U, 0.0, 1.0); return DestVectorType(DestTraits::fromRealPromote(rgb_dest_scale * rgb[0]), DestTraits::fromRealPromote(rgb_dest_scale * rgb[1]), DestTraits::fromRealPromote(rgb_dest_scale * rgb[2])); } protected: ConvertFunctorType converter; const double rgb_dest_scale; const double highlight_lightness_guess_1d_factor; const double highlight_lightness_guess_1d_offset; const unsigned maximum_highlight_iterations; const unsigned maximum_highlight_bracket_tries; const double highlight_simplex_lightness_step_length; const double highlight_simplex_chroma_step_length; const unsigned highlight_iterations_per_leg; const unsigned maximum_highlight_leg; const double shadow_disguised_as_highlight_j; const double shadow_lightness_lightness_guess_factor; const double shadow_lightness_chroma_guess_factor; const double shadow_lightness_guess_offset; const double shadow_chroma_lightness_guess_factor; const double shadow_chroma_chroma_guess_factor; const double shadow_chroma_guess_offset; const double shadow_simplex_lightness_step_length; const double shadow_simplex_chroma_step_length; const unsigned shadow_iterations_per_leg; const unsigned maximum_shadow_leg; const unsigned maximum_multistart_tries; const double optimizer_error; const double optimizer_goal; }; //////////////////////////////////////////////////////////////////////////////////////////////// // // Copy TO pyramid // //////////////////////////////////////////////////////////////////////////////////////////////// // Copy a scalar image into a scalar pyramid image. template inline void copyToPyramidImage(typename SrcImageType::const_traverser src_upperleft, typename SrcImageType::const_traverser src_lowerright, typename SrcImageType::ConstAccessor sa, typename PyramidImageType::traverser dest_upperleft, typename PyramidImageType::Accessor da, vigra::VigraTrueType) { typedef typename SrcImageType::value_type SrcPixelType; typedef typename PyramidImageType::value_type PyramidPixelType; typedef ConvertScalarToPyramidFunctor Converter; vigra::omp::transformImage(src_upperleft, src_lowerright, sa, dest_upperleft, da, Converter()); } // Copy a vector image into a vector pyramid image. Uses an optional color space conversion. template void copyToPyramidImage(typename SrcImageType::const_traverser src_upperleft, typename SrcImageType::const_traverser src_lowerright, typename SrcImageType::ConstAccessor sa, typename PyramidImageType::traverser dest_upperleft, typename PyramidImageType::Accessor da, vigra::VigraFalseType) { typedef typename SrcImageType::value_type SrcVectorType; typedef typename PyramidImageType::value_type PyramidVectorType; typedef ConvertVectorToPyramidFunctor ConverterRGB; typedef ConvertVectorToLabPyramidFunctor ConverterLab; typedef ConvertVectorToLuvPyramidFunctor ConverterLuv; typedef ConvertVectorToJCHPyramidFunctor ConverterJCH; switch (BlendColorspace) { case UndeterminedColorspace: case IdentitySpace: vigra::omp::transformImage(src_upperleft, src_lowerright, sa, dest_upperleft, da, ConverterRGB()); break; case CIELAB: if (Verbose >= VERBOSE_COLOR_CONVERSION_MESSAGES) { std::cerr << command << ": info: CIELAB color conversion"; if (!enblend::profileName(InputProfile).empty()) { std::cerr << " from/to \"" << enblend::profileName(InputProfile) << "\" profile"; } std::cerr << "\n"; } vigra::omp::transformImage(src_upperleft, src_lowerright, sa, dest_upperleft, da, ConverterLab()); break; case CIELUV: if (Verbose >= VERBOSE_COLOR_CONVERSION_MESSAGES) { std::cerr << command << ": info: CIELUV color conversion"; if (!enblend::profileName(InputProfile).empty()) { std::cerr << " from/to \"" << enblend::profileName(InputProfile) << "\" profile"; } std::cerr << "\n"; } vigra::omp::transformImage(src_upperleft, src_lowerright, sa, dest_upperleft, da, ConverterLuv()); break; case CIECAM: if (Verbose >= VERBOSE_COLOR_CONVERSION_MESSAGES) { std::cerr << command << ": info: CIECAM02 color conversion"; if (!enblend::profileName(InputProfile).empty()) { std::cerr << " from/to \"" << enblend::profileName(InputProfile) << "\" profile"; } std::cerr << "\n"; } vigra::omp::transformImage(src_upperleft, src_lowerright, sa, dest_upperleft, da, ConverterJCH()); break; default: NEVER_REACHED("switch control expression \"BlendColorspace\" out of range"); } } // Compile-time switch based on scalar or vector image type. template inline static void copyToPyramidImage(typename SrcImageType::const_traverser src_upperleft, typename SrcImageType::const_traverser src_lowerright, typename SrcImageType::ConstAccessor sa, typename PyramidImageType::traverser dest_upperleft, typename PyramidImageType::Accessor da) { typedef typename vigra::NumericTraits::isScalar src_is_scalar; copyToPyramidImage (src_upperleft, src_lowerright, sa, dest_upperleft, da, src_is_scalar()); } // Version using argument object factories. template inline static void copyToPyramidImage(vigra::triple src, vigra::pair dest) { copyToPyramidImage (src.first, src.second, src.third, dest.first, dest.second); } //////////////////////////////////////////////////////////////////////////////////////////////// // // Conditionally copy FROM pyramid // //////////////////////////////////////////////////////////////////////////////////////////////// // Copy a scalar pyramid image into a scalar image. template inline static void copyFromPyramidImageIf(typename PyramidImageType::const_traverser src_upperleft, typename PyramidImageType::const_traverser src_lowerright, typename PyramidImageType::ConstAccessor sa, typename MaskImageType::const_traverser mask_upperleft, typename MaskImageType::ConstAccessor ma, typename DestImageType::traverser dest_upperleft, typename DestImageType::Accessor da, vigra::VigraTrueType) { typedef typename DestImageType::value_type DestPixelType; typedef typename PyramidImageType::value_type PyramidPixelType; typedef ConvertPyramidToScalarFunctor Converter; vigra::omp::transformImageIf(src_upperleft, src_lowerright, sa, mask_upperleft, ma, dest_upperleft, da, Converter()); } // Copy a vector pyramid image into a vector image. Uses an optional // color space conversion. template inline static void copyFromPyramidImageIf(typename PyramidImageType::const_traverser src_upperleft, typename PyramidImageType::const_traverser src_lowerright, typename PyramidImageType::ConstAccessor sa, typename MaskImageType::const_traverser mask_upperleft, typename MaskImageType::ConstAccessor ma, typename DestImageType::traverser dest_upperleft, typename DestImageType::Accessor da, vigra::VigraFalseType) { typedef typename DestImageType::value_type DestVectorType; typedef typename PyramidImageType::value_type PyramidVectorType; typedef ConvertPyramidToVectorFunctor ConverterRGB; typedef ConvertLabPyramidToVectorFunctor ConverterLab; typedef ConvertLuvPyramidToVectorFunctor ConverterLuv; typedef ConvertJCHPyramidToVectorFunctor ConverterJCH; switch (BlendColorspace) { case UndeterminedColorspace: case IdentitySpace: // OpenMP changes the result here! The maximum absolute // difference is 1 of 255 for 8-bit images. -- cls vigra::omp::transformImageIf(src_upperleft, src_lowerright, sa, mask_upperleft, ma, dest_upperleft, da, ConverterRGB()); break; case CIELAB: if (Verbose >= VERBOSE_COLOR_CONVERSION_MESSAGES) { std::cerr << command << ": info: CIELAB color conversion" << std::endl; } vigra::omp::transformImageIf(src_upperleft, src_lowerright, sa, mask_upperleft, ma, dest_upperleft, da, ConverterLab()); break; case CIELUV: if (Verbose >= VERBOSE_COLOR_CONVERSION_MESSAGES) { std::cerr << command << ": info: CIELUV color conversion" << std::endl; } vigra::omp::transformImageIf(src_upperleft, src_lowerright, sa, mask_upperleft, ma, dest_upperleft, da, ConverterLuv()); break; case CIECAM: if (Verbose >= VERBOSE_COLOR_CONVERSION_MESSAGES) { std::cerr << command << ": info: CIECAM02 color conversion" << std::endl; } vigra::omp::transformImageIf(src_upperleft, src_lowerright, sa, mask_upperleft, ma, dest_upperleft, da, ConverterJCH()); break; default: NEVER_REACHED("switch control expression \"BlendColorspace\" out of range"); } } // Compile-time switch based on scalar or vector image type. template inline static void copyFromPyramidImageIf(typename PyramidImageType::const_traverser src_upperleft, typename PyramidImageType::const_traverser src_lowerright, typename PyramidImageType::ConstAccessor sa, typename MaskImageType::const_traverser mask_upperleft, typename MaskImageType::ConstAccessor ma, typename DestImageType::traverser dest_upperleft, typename DestImageType::Accessor da) { typedef typename vigra::NumericTraits::isScalar src_is_scalar; copyFromPyramidImageIf (src_upperleft, src_lowerright, sa, mask_upperleft, ma, dest_upperleft, da, src_is_scalar()); } // Version using argument object factories. template inline static void copyFromPyramidImageIf(vigra::triple src, vigra::pair mask, vigra::pair dest) { copyFromPyramidImageIf (src.first, src.second, src.third, mask.first, mask.second, dest.first, dest.second); } } // namespace enblend #endif // FIXMATH_H_INCLUDED_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/graphcut.h0000644000175000017500000016545412673200620013764 00000000000000/* * Copyright (C) 2011-2016 Mikolaj Leszczynski * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef GRAPHCUT_H #define GRAPHCUT_H #include #ifdef _WIN32 #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rect2d.hxx" #include "stride.hxx" #include "common.h" #include "maskcommon.h" #include "masktypedefs.h" #include "nearest.h" using namespace vigra::functor; #define BIT_MASK_DIR 0x03 #define BIT_MASK_OPDIR 0x02 #define BIT_MASK_OPEN 0x04 #define BIT_MASK_DIVIDE 0x0F #define LABEL_NONE 0 #define LABEL_LEFT 1 #define LABEL_RIGHT 2 //#define DEBUG_GRAPHCUT namespace enblend { template inline void hash_combine(std::size_t & seed, const T & value) { std::hash hasher; seed ^= hasher(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } struct pointHash { std::size_t operator()(const vigra::Point2D& p) const { std::size_t seed = 0; hash_combine(seed, p.x); hash_combine(seed, p.y); return seed; } }; class CheckpointPixels { public: CheckpointPixels() {} std::unordered_set top, bottom; ~CheckpointPixels() { this->clear(); } void clear() { top.clear(); bottom.clear(); } }; int distab(const vigra::Point2D& a, const vigra::Point2D& b) { return std::abs((a.x - b.x)) + std::abs((a.y - b.y)); } template std::vector* findIntermediatePoints(MaskImageIterator mask1_upperleft, MaskImageIterator mask1_lowerright, MaskAccessor ma1, MaskImageIterator mask2_upperleft, MaskAccessor ma2, DestImageIterator dest_upperleft, DestAccessor da, nearest_neighbor_metric_t& norm, boundary_t& boundary, const vigra::Rect2D& iBB) { typedef vigra::NumericTraits MaskPixelTraits; typedef typename IMAGETYPE::traverser IteratorType; typedef vigra::CrackContourCirculator Circulator; typedef vigra::triple EntryPointContainer; IMAGETYPE nftTempImg(mask1_lowerright - mask1_upperleft + vigra::Diff2D(2, 2)); IMAGETYPE nft(iBB.lowerRight() - iBB.upperLeft() + vigra::Diff2D(2, 2)); IMAGETYPE overlap(iBB.lowerRight() - iBB.upperLeft() + vigra::Diff2D(2, 2)); IteratorType nftIter = nft.upperLeft(); IteratorType previous; Circulator* circ; Circulator* end; bool offTheBorder = false; bool inOverlap = false; bool ready = false; std::vector* interPointList = new std::vector(); std::vector entryPointList; EntryPointContainer* max = nullptr; std::pair entryPoint; vigra::Point2D intermediatePoint; unsigned int counter = 0; vigra::initImage(vigra::destImageRange(nftTempImg), MaskPixelTraits::max() / 2); vigra::initImage(vigra::destImageRange(nft), MaskPixelTraits::max() / 2); nearestFeatureTransform(vigra::srcIterRange(mask1_upperleft, mask1_lowerright, ma1), vigra::srcIter(mask2_upperleft, ma2), vigra::destIter(nftTempImg.upperLeft() + vigra::Diff2D(1, 1)), norm, boundary); vigra::copyImage(vigra::srcIterRange(nftTempImg.upperLeft() + vigra::Diff2D(1, 1), nftTempImg.lowerRight() - vigra::Diff2D(1, 1)), vigra::destIter(dest_upperleft, da)); vigra::copyImage(vigra_ext::apply(iBB, vigra::srcIterRange(nftTempImg.upperLeft() + vigra::Diff2D(1, 1), nftTempImg.lowerRight() - vigra::Diff2D(1, 1))), vigra::destIter(nft.upperLeft() + vigra::Diff2D(1, 1))); vigra::omp::combineTwoImages(vigra_ext::apply(iBB, vigra::srcIterRange(mask1_upperleft, mask1_lowerright, ma1)), vigra_ext::apply(iBB, vigra::srcIter(mask2_upperleft, ma2)), vigra::destIter(overlap.upperLeft() + vigra::Diff2D(1, 1)), ifThenElse(Arg1() && Arg2(), Param(MaskPixelTraits::max()), Param(MaskPixelTraits::zero()))); #ifdef DEBUG_GRAPHCUT exportImage(srcImageRange(nftTempImg), ImageExportInfo("./debug/nft-orig.tif").setPixelType("UINT8")); exportImage(srcImageRange(nft), ImageExportInfo("./debug/nfttotal.tif").setPixelType("UINT8")); exportImage(srcImageRange(overlap), ImageExportInfo("./debug/overlap.tif").setPixelType("UINT8")); #endif circ = new Circulator(nftIter + vigra::Diff2D(1, 0), vigra::FourNeighborCode::South); end = new Circulator(nftIter + vigra::Diff2D(1, 0), vigra::FourNeighborCode::South); previous = circ->outerPixel(); do { (*circ)++; if (nft.accessor()(previous) != nft.accessor()(circ->outerPixel())) { if (ready) { entryPointList.push_back(EntryPointContainer(entryPoint.first, entryPoint.second, counter)); entryPoint.first = previous; entryPoint.second = circ->outerPixel(); } else { ready = true; entryPoint = std::pair(previous, circ->outerPixel()); } counter = 0; } ++counter; previous = circ->outerPixel(); } while (*circ != *end); if (entryPointList.empty()) { return interPointList; } for (typename std::vector::iterator i = entryPointList.begin(); i != entryPointList.end(); ++i) { if (max == nullptr) { max = &(*i); continue; } if (i->third > max->third) { max = &(*i); } } if (max != nullptr) { delete circ; delete end; vigra::Diff2D dir = max->second - max->first; if (dir.x != 0) { if (max->second.x < max->first.x) { max->second = max->first; } circ = new Circulator(max->second, vigra::FourNeighborCode::West); end = new Circulator(max->second, vigra::FourNeighborCode::West); } else if (dir.y != 0) { if (max->second.y < max->first.y) { max->second = max->first; } circ = new Circulator(max->second, vigra::FourNeighborCode::North); end = new Circulator(max->second, vigra::FourNeighborCode::North); } } else { return interPointList; } while (circ != end) { (*circ)++; intermediatePoint = circ->outerPixel() - nft.upperLeft(); if (!offTheBorder && !(nft.accessor()(circ->outerPixel()) == MaskPixelTraits::max() / 2)) { offTheBorder = true; const vigra::Point2D dualGraphPoint = vigra::Point2D(intermediatePoint * 2 - vigra::Diff2D(1, 1)); if (intermediatePoint.x >= 0 && intermediatePoint.y >= 0 && intermediatePoint.x < iBB.lowerRight().x && intermediatePoint.y < iBB.lowerRight().y) { interPointList->push_back(dualGraphPoint); } #ifdef DEBUG_GRAPHCUT std::cout << "Start point: " << dualGraphPoint << std::endl; #endif } if (offTheBorder) { if (!inOverlap && overlap[intermediatePoint] == MaskPixelTraits::max()) { inOverlap = true; const vigra::Point2D dualGraphPoint = vigra::Point2D(intermediatePoint * 2 - vigra::Diff2D(1, 1)); if (!interPointList->empty() && *(interPointList->begin()) != dualGraphPoint && intermediatePoint.x >= 0 && intermediatePoint.y >= 0) { interPointList->push_back(dualGraphPoint); } #ifdef DEBUG_GRAPHCUT std::cout << "Entering overlap: " << dualGraphPoint << std::endl; #endif } if (inOverlap && overlap[intermediatePoint] == MaskPixelTraits::zero() && nft.accessor()(circ->outerPixel()) != MaskPixelTraits::max() / 2) { inOverlap = false; const vigra::Point2D dualGraphPoint = vigra::Point2D(intermediatePoint * 2 - vigra::Diff2D(1, 1)); if (intermediatePoint.x >= 0 && intermediatePoint.y >= 0) { interPointList->push_back(dualGraphPoint); } #ifdef DEBUG_GRAPHCUT std::cout << "Leaving overlap: " << dualGraphPoint << std::endl; #endif } if (nft.accessor()(circ->outerPixel()) == MaskPixelTraits::max() / 2) { const vigra::Point2D dualGraphPoint = vigra::Point2D((previous - nft.upperLeft()) * 2 - vigra::Diff2D(1, 1)); if (!interPointList->empty() && *(interPointList->rbegin()) != dualGraphPoint && intermediatePoint.x >= 0 && intermediatePoint.y >= 0) { interPointList->push_back(dualGraphPoint); } #ifdef DEBUG_GRAPHCUT std::cout << "Endpoint reached: " << dualGraphPoint << std::endl; #endif break; } } previous = circ->outerPixel(); } delete circ; delete end; return interPointList; } template class CostComparer { public: CostComparer(const ImageType* image) : img(image) {} bool operator()(const vigra::Point2D& a, const vigra::Point2D& b) const { if (a == vigra::Point2D(-20, -20)) { return totalScore > (*img)[b]; } else if (b == vigra::Point2D(-20, -20)) { return (*img)[a] > totalScore; } return (*img)[a] > (*img)[b]; } void setTotalScore(long s) { totalScore = s; } protected: const ImageType* img; long totalScore; }; template struct OutputLabelingFunctor { public: OutputLabelingFunctor(std::unordered_set* a_, std::unordered_set* b_, vigra::Point2D offset_) : left(a_), right(b_), offset(offset_) {} MaskPixelType operator()(const vigra::Diff2D& a_point) const { vigra::Point2D point(a_point); // add border to detect seams close to border point -= vigra::Point2D(1,1); if(left->find(point) != left->end()) return LABEL_LEFT; else if (right->find(point) != right->end()) return LABEL_RIGHT; else return LABEL_NONE; } protected: std::unordered_set* left; std::unordered_set* right; vigra::Point2D offset; }; template struct CutPixelsFunctor { public: CutPixelsFunctor(std::unordered_set* a_, std::unordered_set* b_) : left(a_), right(b_){} MaskPixelType operator()(const vigra::Diff2D& pos2, const MaskPixelType& a2) const { vigra::Point2D pos(pos2); if(left->find(pos) != left->end() && right->find(pos) != right->end()) return 164; else if (left->find(*pos) != left->end()) return 64; else if (right->find(*pos) != right->end()) return 255; else return 0; } protected: std::unordered_set* left; std::unordered_set* right; }; template struct CountFunctor { public: CountFunctor(long* c, long* c2) : color(c), count(c2) {} MaskPixelType operator()(const MaskPixelType& arg1, const MaskPixelType& arg2) const { if (arg1 == LABEL_LEFT && arg2 == 255) { (*color)++; } if (arg1 == LABEL_LEFT) { (*count)++; } return arg1; } long* color; long* count; }; template inline void graphCut(vigra::triple src1, vigra::pair src2, vigra::pair dest, vigra::triple mask1, vigra::pair mask2, nearest_neighbor_metric_t norm, boundary_t boundary, const vigra::Rect2D& iBB) { graphCut(src1.first, src1.second, src1.third, src2.first, src2.second, dest.first, dest.second, mask1.first, mask1.second, mask1.third, mask2.first, mask2.second, norm, boundary, iBB); } void getNeighbourList(vigra::Point2D src, vigra::Point2D* list, vigra::Diff2D bounds, CheckpointPixels* srcDestPoints) { // return neighbour points from top to left in clockwise order bool check = false; if (src.y == 1) { list[0] = vigra::Point2D(-1, -1); check = true; } else { list[0] = src(0, -2); } if (src.x == bounds.x - 1) { list[1] = vigra::Point2D(-1, -1); check = true; } else { list[1] = src(2, 0); } if (src.y == bounds.y - 1) { list[2] = vigra::Point2D(-1, -1); check = true; } else { list[2] = src(0, 2); } if (src.x == 1) { list[3] = vigra::Point2D(-1, -1); check = true; } else { list[3] = src(-2, 0); } if (srcDestPoints->bottom.find(src) != srcDestPoints->bottom.end()) { list[0] = vigra::Point2D(-20, -20); list[1] = vigra::Point2D(-20, -20); list[2] = vigra::Point2D(-20, -20); list[3] = vigra::Point2D(-20, -20); } if (check) { if (srcDestPoints->bottom.find(src) != srcDestPoints->bottom.end() || srcDestPoints->bottom.find(src(1, 0)) != srcDestPoints->bottom.end() || srcDestPoints->bottom.find(src(1, 1)) != srcDestPoints->bottom.end() || srcDestPoints->bottom.find(src(0, 1)) != srcDestPoints->bottom.end()) { if (list[1] == vigra::Point2D(-1, -1)) { list[1] = vigra::Point2D(-20, -20); } else if (list[2] == vigra::Point2D(-1, -1)) { list[2] = vigra::Point2D(-20, -20); } else if (list[3] == vigra::Point2D(-1, -1)) { list[3] = vigra::Point2D(-20, -20); } } } } void getNeighbourList(CheckpointPixels* srcDestPoints, std::unordered_set::iterator* auxList1, std::unordered_set::iterator* auxList2) { *auxList1 = srcDestPoints->top.begin(); *auxList2 = srcDestPoints->top.end(); } template std::vector* tracePath(vigra::Point2D pt, ImageType* img, CheckpointPixels* srcDestPoints) { std::vector* vec = new std::vector; vigra::Point2D current = pt; vec->push_back(pt); do { switch ((*img)[current(1, 1)] & BIT_MASK_DIR) { case 0: vec->push_back(current(0, -2)); break; case 1: vec->push_back(current(2, 0)); break; case 2: vec->push_back(current(0, 2)); break; case 3: vec->push_back(current(-2, 0)); break; default: #ifdef DEBUG_GRAPHCUT std::cout << "path tracing error" << std::endl; #endif break; } current = vec->back(); } while (srcDestPoints->top.find(current) == srcDestPoints->top.end()); return vec; } template unsigned int getEdgeWeight(int dir, vigra::Point2D pt, ImageType* img, bool endpt, vigra::Diff2D bounds) { if (!endpt) { switch (dir) { case 0: return (*img)[pt(1, 0)]; break; case 1: return (*img)[pt(2, 1)]; break; case 2: return (*img)[pt(1, 2)]; break; case 3: return (*img)[pt(0, 1)]; break; } } else { if (pt.y == 1) { return (*img)[pt(1, 0)]; } else if (pt.x == bounds.x - 2) { return (*img)[pt(2, 1)]; } else if (pt.y == bounds.y - 2) { return (*img)[pt(1, 2)]; } else if (pt.x == 1) { return (*img)[pt(0, 1)]; } } return 0; } template std::vector* A_star(vigra::Point2D srcpt, vigra::Point2D destpt, ImageType* img, GradientImageType* gradientX, GradientImageType* gradientY, vigra::Diff2D bounds, CheckpointPixels* srcDestPoints, std::unordered_set* visited) { MaskPixelType zeroVal = vigra::NumericTraits::zero(); typedef std::priority_queue, CostComparer > Queue; CostComparer costcomp(img); Queue* openset = new Queue(costcomp); long score = 0; long totalScore = 0; long iterCount = 0; int gradientA; int gradientB; bool scoreIsBetter; bool pushToList; bool destOpen = false; vigra::Point2D list[4]; vigra::Point2D current; vigra::Point2D neighbour; vigra::Point2D destNeighbour; std::unordered_set::iterator auxListBegin; std::unordered_set::iterator auxListEnd; openset->push(srcpt); while (!openset->empty()) { current = openset->top(); openset->pop(); iterCount++; if (current == destpt) { #ifdef DEBUG_GRAPHCUT std::cout << "Graphcut completed after visiting " << iterCount << " nodes" << std::endl; #endif delete openset; return tracePath(destNeighbour, img, srcDestPoints); } if (current == vigra::Point2D(-10, -10)) { getNeighbourList(srcDestPoints, &auxListBegin, &auxListEnd); } else { getNeighbourList(current, list, bounds, srcDestPoints); } if (current != vigra::Point2D(-10, -10)) { for (int i = 0; i < 4; i++) { score = 0; scoreIsBetter = false; pushToList = false; neighbour = list[i]; //visited during an earlier sub-cut, ignore if(visited->find(neighbour) != visited->end()) { continue; } if (neighbour == vigra::Point2D(-20, -20) || (neighbour != vigra::Point2D(-1, -1) && neighbour != vigra::Point2D(-10, -10) && (*img)[neighbour(1, 1)] == zeroVal)) { if (neighbour == vigra::Point2D(-20, -20)) { score = (*img)[current] + getEdgeWeight(i, current, img, true, bounds); } else { if (i % 2 == 0) { gradientA = std::abs((*gradientY)[(current) / 2]); gradientB = std::abs((*gradientY)[(neighbour) / 2]); } else { gradientA = std::abs((*gradientX)[(current) / 2]); gradientB = std::abs((*gradientX)[(neighbour) / 2]); } if (gradientA + gradientB > 0) { score = (*img)[current] + getEdgeWeight(i, current, img, false, bounds) * (gradientA + gradientB); } else { score = (*img)[current] + getEdgeWeight(i, current, img, false, bounds); } } if (neighbour == vigra::Point2D(-20, -20) && !destOpen) { pushToList = true; destOpen = true; scoreIsBetter = true; } else if (neighbour != vigra::Point2D(-20, -20) && ((*img)[neighbour(1, 1)] & BIT_MASK_OPEN) == 0) { pushToList = true; (*img)[neighbour(1, 1)] += BIT_MASK_OPEN; scoreIsBetter = true; } else if ((neighbour == vigra::Point2D(-20, -20) && score < totalScore) || (neighbour != vigra::Point2D(-20, -20) && score < (*img)[neighbour])) { scoreIsBetter = true; } if (scoreIsBetter) { if (neighbour == vigra::Point2D(-20, -20)) { totalScore = score; destNeighbour = current; costcomp.setTotalScore(totalScore); } else { (*img)[neighbour(1, 1)] &= BIT_MASK_OPEN; (*img)[neighbour(1, 1)] += i; (*img)[neighbour(1, 1)] ^= BIT_MASK_OPDIR; (*img)[neighbour] = score; } if (pushToList) { openset->push(neighbour); } } } } } else { for (std::unordered_set::iterator x = auxListBegin; x != auxListEnd; ++x) { score = 0; scoreIsBetter = false; pushToList = false; neighbour = *x; if (neighbour != vigra::Point2D(-1, -1) && (*img)[neighbour(1, 1)] == zeroVal) { score = 0; if (((*img)[neighbour(1, 1)] & BIT_MASK_OPEN) == 0) { pushToList = true; (*img)[neighbour(1, 1)] += BIT_MASK_OPEN; scoreIsBetter = true; } else if (score < (*img)[neighbour]) { scoreIsBetter = true; } if (scoreIsBetter) { (*img)[neighbour(1, 1)] &= BIT_MASK_OPEN; (*img)[neighbour] = score; if (pushToList) { openset->push(neighbour); } } } } } } #ifdef DEBUG_GRAPHCUT std::cout << "Graphcut failed after visiting " << iterCount << " nodes" << std::endl; #endif delete openset; return new std::vector(); } vigra::Point2D convertFromDual(const vigra::Point2D& dualPixel) { const int stride = 2; return (vigra::Point2D((dualPixel->x - 1) / stride, (dualPixel->y - 1) / stride)); } void dividePath(std::vector* cut, std::unordered_set* left, std::unordered_set* right, const vigra::Rect2D& iBB) { vigra::Point2D previous; vigra::Point2D current; vigra::Point2D next; vigra::Point2D endIterPoint; unsigned short closest = 0; vigra::Diff2D dim(iBB.lowerRight() - iBB.upperLeft()); std::vector::iterator previousDual; std::vector::iterator nextDual; for (std::vector::iterator currentDual = cut->begin(), nextDual = cut->begin(); currentDual != cut->end(); ++currentDual) { current = convertFromDual(*currentDual); if (nextDual != cut->end()) { next = convertFromDual(*nextDual); } if (currentDual == cut->begin()) { ++nextDual; next = convertFromDual(*nextDual); // find closest edge int dist; const vigra::Diff2D toLowerRight = dim - current; closest = 0; dist = current.y; if (toLowerRight.x < dist) { closest = 1; dist = toLowerRight.x; } if (toLowerRight.y < dist) { closest = 2; dist = toLowerRight.y; } if (current.x < dist) { closest = 3; } switch (closest) { case 0: right->insert(current(0, 0)); left->insert(current(1, 0)); break; case 1: left->insert(current(1, 1)); right->insert(current(1, 0)); break; case 2: left->insert(current(0, 1)); right->insert(current(1, 1)); break; case 3: right->insert(current(0, 1)); left->insert(current(0, 0)); break; default: #ifdef DEBUG_GRAPHCUT std::cout << "path dividing error" << std::endl; #endif break; } int previousDir; if (next.x == current.x) { if (next.y < current.y) { previousDir = 0; } else { previousDir = 2; } } else { if (next.x > current.x) { previousDir = 1; } else { previousDir = 3; } } switch (closest) { case 0: switch (previousDir) { case 2: right->insert(current(0, 1)); left->insert(current(1, 1)); break; case 1: right->insert(current(0, 1)); right->insert(current(1, 1)); break; case 3: left->insert(current(0, 1)); left->insert(current(1, 1)); break; case 0: left->insert(current(0, 0)); right->insert(current(1, 0)); break; default: #ifdef DEBUG_GRAPHCUT std::cout << "path dividing error" << std::endl; #endif break; } break; case 1: switch (previousDir) { case 0: left->insert(current(0, 0)); left->insert(current(0, 1)); break; case 2: right->insert(current(0, 0)); right->insert(current(0, 1)); break; case 3: right->insert(current(0, 0)); left->insert(current(0, 1)); break; case 1: right->insert(current(1, 1)); left->insert(current(1, 0)); break; default: #ifdef DEBUG_GRAPHCUT std::cout << "path dividing error" << std::endl; #endif break; } break; case 2: switch (previousDir) { case 0: left->insert(current); right->insert(current(1, 0)); break; case 1: left->insert(current); left->insert(current(1, 0)); break; case 3: right->insert(current); right->insert(current(1, 0)); break; case 2: left->insert(current(1, 1)); right->insert(current(0, 1)); break; default: #ifdef DEBUG_GRAPHCUT std::cout << "path dividing error" << std::endl; #endif break; } break; case 3: switch (previousDir) { case 2: left->insert(current(1, 0)); left->insert(current(1, 1)); break; case 0: right->insert(current(1, 0)); right->insert(current(1, 1)); break; case 1: right->insert(current(1, 1)); left->insert(current(1, 0)); break; case 3: right->insert(current(0, 0)); left->insert(current(0, 1)); break; default: #ifdef DEBUG_GRAPHCUT std::cout << "path dividing error" << std::endl; #endif break; } break; } switch (closest) { case 0: endIterPoint = current; while (endIterPoint.y + iBB.upperLeft().y > -2) { endIterPoint.y--; left->insert(endIterPoint(1, 0)); right->insert(endIterPoint); } break; case 1: endIterPoint = current; while (endIterPoint.x < iBB.lowerRight().x + 2) { endIterPoint.x++; left->insert(endIterPoint(0, 1)); right->insert(endIterPoint); } break; case 2: endIterPoint = current; while (endIterPoint.y < iBB.lowerRight().y + 2) { endIterPoint.y++; left->insert(endIterPoint); right->insert(endIterPoint(1, 0)); } break; case 3: endIterPoint = current; while (endIterPoint.x > -2) { endIterPoint.x--; left->insert(endIterPoint); right->insert(endIterPoint(0, 1)); } break; default: #ifdef DEBUG_GRAPHCUT std::cout << "path dividing error" << std::endl; #endif break; } } else { int previousDir; int currentDir; if (previous.x == current.x) { if (previous.y > current.y) { previousDir = 0; } else { previousDir = 2; } } else { if (previous.x < current.x) { previousDir = 1; } else { previousDir = 3; } } previousDir = previousDir << 2; if (nextDual == cut->end()) { int dist; const vigra::Diff2D toLowerRight = dim - current; closest = 0; dist = current.y; if (toLowerRight.x < dist) { closest = 1; dist = toLowerRight.x; } if (toLowerRight.y < dist) { closest = 2; dist = toLowerRight.y; } if (current.x < dist) { closest = 3; } currentDir = closest; } else if (next.x == current.x) { if (next.y < current.y) { currentDir = 0; } else { currentDir = 2; } } else { if (next.x > current.x) { currentDir = 1; } else { currentDir = 3; } } switch (previousDir + currentDir) { case 0: // top -> top left->insert(current); right->insert(current(1, 0)); left->insert(current(0, 1)); right->insert(current(1, 1)); break; case 1: // top -> right left->insert(current); left->insert(current(1, 0)); left->insert(current(0, 1)); right->insert(current(1, 1)); break; case 3: // top -> left right->insert(current); right->insert(current(1, 0)); left->insert(current(0, 1)); right->insert(current(1, 1)); break; case 4: // right->top left->insert(current); right->insert(current(1, 0)); right->insert(current(0, 1)); right->insert(current(1, 1)); break; case 5: // right->right left->insert(current); left->insert(current(1, 0)); right->insert(current(0, 1)); right->insert(current(1, 1)); break; case 6: // right->bottom left->insert(current); left->insert(current(1, 0)); right->insert(current(0, 1)); left->insert(current(1, 1)); break; case 9: // bottom->right right->insert(current); left->insert(current(1, 0)); right->insert(current(0, 1)); right->insert(current(1, 1)); break; case 10: // bottom->bottom right->insert(current); left->insert(current(1, 0)); right->insert(current(0, 1)); left->insert(current(1, 1)); break; case 11: // bottom->left right->insert(current); left->insert(current(1, 0)); left->insert(current(0, 1)); left->insert(current(1, 1)); break; case 12: // left->top left->insert(current); right->insert(current(1, 0)); left->insert(current(0, 1)); left->insert(current(1, 1)); break; case 14: // left->bottom right->insert(current); right->insert(current(1, 0)); right->insert(current(0, 1)); left->insert(current(1, 1)); break; case 15: // left->left right->insert(current); right->insert(current(1, 0)); left->insert(current(0, 1)); left->insert(current(1, 1)); break; case 2: // top -> bottom case 7: // right->left case 8: // bottom->top case 13: // left->right default: #ifdef DEBUG_GRAPHCUT std::cout << "path dividing error: two-point loop" << std::endl; std::cout << current << std::endl; #endif break; } if (*currentDual == cut->back()) { switch (closest) { case 2: endIterPoint = current; switch (currentDir) { case 1: left->insert(current); left->insert(current(1, 0)); right->insert(current(0, 1)); left->insert(current(1, 1)); break; case 3: right->insert(current); right->insert(current(1, 0)); right->insert(current(0, 1)); left->insert(current(1, 1)); break; } while (endIterPoint.y < iBB.lowerRight().y + 2) { endIterPoint.y++; left->insert(endIterPoint(1, 0)); right->insert(endIterPoint); } break; case 3: endIterPoint = current; switch (currentDir) { case 0: right->insert(current); right->insert(current(1, 0)); left->insert(current(0, 1)); right->insert(current(1, 1)); break; case 2: right->insert(current); left->insert(current(1, 0)); left->insert(current(0, 1)); left->insert(current(1, 1)); break; } while (endIterPoint.x > -2) { endIterPoint.x--; left->insert(endIterPoint(0, 1)); right->insert(endIterPoint); } break; case 0: endIterPoint = current; switch (currentDir) { case 1: left->insert(current); right->insert(current(1, 0)); right->insert(current(0, 1)); right->insert(current(1, 1)); break; case 3: left->insert(current); right->insert(current(1, 0)); left->insert(current(0, 1)); left->insert(current(1, 1)); break; } while (endIterPoint.y + iBB.upperLeft().y > -2) { endIterPoint.y--; left->insert(endIterPoint); right->insert(endIterPoint(1, 0)); } break; case 1: endIterPoint = current; switch (currentDir) { case 0: left->insert(current); left->insert(current(1, 0)); left->insert(current(0, 1)); right->insert(current(1, 1)); break; case 2: right->insert(current); left->insert(current(1, 0)); right->insert(current(0, 1)); right->insert(current(1, 1)); break; } while (endIterPoint.x < iBB.lowerRight().x + 2) { endIterPoint.x++; left->insert(endIterPoint); right->insert(endIterPoint(0, 1)); } break; default: #ifdef DEBUG_GRAPHCUT std::cout << "path dividing error" << std::endl; #endif break; } } } if (nextDual != cut->end()) { ++nextDual; } previous = current; previousDual = currentDual; } } template void processCutResults(MaskImageIterator mask1_upperleft, MaskImageIterator mask1_lowerright, MaskAccessor ma1, MaskImageIterator mask2_upperleft, MaskAccessor ma2, DestImageIterator dest_upperleft, DestAccessor da, std::vector& totalDualPath, const vigra::Rect2D& iBB) { const vigra::Diff2D size(iBB.lowerRight().x - iBB.upperLeft().x, iBB.lowerRight().y - iBB.upperLeft().y); IMAGETYPE finalmask(size); IMAGETYPE tempImg(size); typedef vigra::UInt8 BasePixelType; typedef vigra::NumericTraits BasePixelTraits; typedef vigra::NumericTraits MaskPixelTraits; std::unordered_set pixelsLeftOfCut; std::unordered_set pixelsRightOfCut; dividePath(&totalDualPath, &pixelsLeftOfCut, &pixelsRightOfCut, iBB); #ifdef DEBUG_GRAPHCUT vigra::omp::combineTwoImages(srcIterRange(Diff2D(), size), vigra::srcIter(finalmask.upperLeft()), vigra::destIter(tempImg.upperLeft()), CutPixelsFunctor(&pixelsLeftOfCut, &pixelsRightOfCut)); exportImage(srcImageRange(tempImg), ImageExportInfo("./debug/process_cut_1_seam_pixels.tif").setPixelType("UINT8")); #endif vigra::transformImage(srcIterRange(vigra::Diff2D(), size), vigra::destIter(tempImg.upperLeft()), OutputLabelingFunctor(&pixelsLeftOfCut, &pixelsRightOfCut, iBB.upperLeft())); // labels areas that belong to left/right images // adds a 1-pixel border to catch any area that is cut off by the seam vigra::ArrayOfRegionStatistics > stats(3); vigra::seededRegionGrowing(srcImageRange(tempImg), srcImage(tempImg), destImage(finalmask), stats); const vigra::triple::Iterator, typename IMAGETYPE::Iterator, typename IMAGETYPE::Accessor> finalmaskSrcRange = vigra::srcIterRange(finalmask.upperLeft() + vigra::Diff2D(1, 1), finalmask.lowerRight() - vigra::Diff2D(1, 1)); const vigra::pair::Iterator, typename IMAGETYPE::Accessor> finalmaskDest = vigra::destIter(finalmask.upperLeft() + vigra::Diff2D(1, 1)); #ifdef DEBUG_GRAPHCUT exportImage(srcImageRange(tempImg), ImageExportInfo("./debug/process_cut_2_seam_labels.tif").setPixelType("UINT8")); exportImage(finalmaskSrcRange, ImageExportInfo("./debug/process_cut_3_segments.tif").setPixelType("UINT8")); #endif long colorSum = 0; long count = 0; CountFunctor countFunctor(&colorSum, &count); inspectTwoImages(finalmaskSrcRange, vigra::srcIter(dest_upperleft + iBB.upperLeft(), da), countFunctor); // if colorSum < half the pixels labeled as LABEL_LEFT in finalmask should be white if (colorSum < count / 2) { transformImage(finalmaskSrcRange, finalmaskDest, ifThenElse(Arg1() == Param(LABEL_LEFT), Param(BasePixelTraits::zero()), Param(BasePixelTraits::max()))); } else { transformImage(finalmaskSrcRange, finalmaskDest, ifThenElse(Arg1() == Param(LABEL_LEFT), Param(BasePixelTraits::max()), Param(BasePixelTraits::zero()))); } #ifdef DEBUG_GRAPHCUT exportImage(finalmaskSrcRange, ImageExportInfo("./debug/process_cut_4_final_precopy.tif").setPixelType("UINT8")); #endif vigra::omp::combineTwoImages(vigra_ext::apply(iBB, vigra::srcIterRange(mask1_upperleft, mask1_lowerright, ma1)), vigra_ext::apply(iBB, vigra::srcIter(mask2_upperleft, ma2)), destImage(tempImg), ifThenElse(Arg1() && Arg2(), Param(MaskPixelTraits::max()), Param(MaskPixelTraits::zero()))); vigra::copyImageIf(finalmaskSrcRange, srcImage(tempImg), vigra::destIter(dest_upperleft + iBB.upperLeft(), da)); #ifdef DEBUG_GRAPHCUT exportImage(srcIterRange(dest_upperleft + iBB.upperLeft(), dest_upperleft + iBB.upperLeft() + size), ImageExportInfo("./debug/process_cut_5_final_postcopy.tif").setPixelType("UINT8")); #endif } /* Graph-cut * implementation of an algorithm based on an article by: * V.Kwatra, A.Schoedl, I.Essa, G.Turk, A.Bobick * "Graphcut Textures: Image and Video Synthesis Using Graph Cuts" * * The algorithm finds the best seam between two images using a graph-based approach. * * Min-cost pathfinding is based on using the initial image graph's dual graph */ template void graphCut(SrcImageIterator src1_upperleft, SrcImageIterator src1_lowerright, SrcAccessor sa1, SrcImageIterator src2_upperleft, SrcAccessor sa2, DestImageIterator dest_upperleft, DestAccessor da, MaskImageIterator mask1_upperleft, MaskImageIterator mask1_lowerright, MaskAccessor ma1, MaskImageIterator mask2_upperleft, MaskAccessor ma2, nearest_neighbor_metric_t norm, boundary_t boundary, const vigra::Rect2D& iBB) { typedef typename SrcAccessor::value_type SrcPixelType; typedef typename MaskAccessor::value_type MaskPixelType; typedef vigra::UInt8 BasePixelType; typedef float GradientPixelType; typedef vigra::NumericTraits BasePixelTraits; typedef typename BasePixelTraits::Promote BasePromotePixelType; typedef vigra::NumericTraits BasePromotePixelTraits; typedef typename BasePromotePixelTraits::Promote GraphPixelType; const vigra::Diff2D size(src1_lowerright.x - src1_upperleft.x, src1_lowerright.y - src1_upperleft.y); #ifdef DEBUG_GRAPHCUT const vigra::Diff2D masksize(mask1_lowerright.x - mask1_upperleft.x, mask1_lowerright.y - mask1_upperleft.y); #endif IMAGETYPE intermediateImg(size); IMAGETYPE intermediateGraphImg(size + size + vigra::Diff2D(1, 1)); IMAGETYPE gradientPreConvolve(size); IMAGETYPE gradientX(size); IMAGETYPE gradientY(size); IMAGETYPE graphImg(size + size + vigra::Diff2D(1, 1)); std::vector* dualPath = nullptr; std::vector totalDualPath; vigra::Point2D intermediatePoint; CheckpointPixels srcDestPoints; const vigra::Diff2D graphsize(graphImg.lowerRight().x - graphImg.upperLeft().x, graphImg.lowerRight().y - graphImg.upperLeft().y); const vigra::Rect2D gBB(vigra::Point2D(1, 1), vigra::Size2D(graphsize)); vigra::Kernel2D edgeWeightKernel; edgeWeightKernel.initExplicitly(vigra::Diff2D(-1, -1), vigra::Diff2D(1, 1)) = // upper left and lower right 0, 1, 0, 1, 1, 1, 0, 1, 0; edgeWeightKernel.setBorderTreatment(vigra::BORDER_TREATMENT_CLIP); vigra::Kernel1D gradientKernel; gradientKernel.initSymmetricGradient(); // gradient images calculation transformImage(src1_upperleft, src1_lowerright, sa1, gradientPreConvolve.upperLeft(), gradientPreConvolve.accessor(), MapFunctor()); transformImage(src2_upperleft, src2_upperleft + size, sa2, intermediateImg.upperLeft(), intermediateImg.accessor(), MapFunctor()); vigra::omp::combineTwoImages(srcImageRange(gradientPreConvolve), srcImage(intermediateImg), destImage(gradientPreConvolve), Arg1() + Arg2()); // computing image gradient for a better cost function vigra::separableConvolveX(srcImageRange(gradientPreConvolve), destImage(gradientX), vigra::kernel1d(gradientKernel)); vigra::separableConvolveY(srcImageRange(gradientPreConvolve), destImage(gradientY), vigra::kernel1d(gradientKernel)); // difference image calculation switch (PixelDifferenceFunctor) { case HueLuminanceMaxDifference: vigra::omp::combineTwoImages(src1_upperleft, src1_lowerright, sa1, src2_upperleft, sa2, intermediateImg.upperLeft(), intermediateImg.accessor(), MaxHueLuminanceDifferenceFunctor (LuminanceDifferenceWeight, ChrominanceDifferenceWeight)); break; case DeltaEDifference: vigra::omp::combineTwoImages(src1_upperleft, src1_lowerright, sa1, src2_upperleft, sa2, intermediateImg.upperLeft(), intermediateImg.accessor(), DeltaEPixelDifferenceFunctor (LuminanceDifferenceWeight, ChrominanceDifferenceWeight)); break; default: NEVER_REACHED("switch control expression \"PixelDifferenceFunctor\" out of range"); } // masking overlap region borders vigra::omp::combineThreeImages(vigra_ext::apply(iBB, vigra::srcIterRange(mask1_upperleft, mask1_lowerright, ma1)), vigra_ext::apply(iBB, vigra::srcIter(mask2_upperleft, ma2)), vigra::srcIter(intermediateImg.upperLeft(), intermediateImg.accessor()), vigra::destIter(intermediateImg.upperLeft(), intermediateImg.accessor()), ifThenElse(!(Arg1() & Arg2()), Param(BasePixelTraits::max()), Arg3())); // look for possible start and end points std::vector* intermediatePointList = findIntermediatePoints (mask1_upperleft, mask1_lowerright, ma1, mask2_upperleft, ma2, dest_upperleft, da, norm, boundary, iBB); // in case something goes wrong with start/end point finding, returns regular nft image if (intermediatePointList->empty()) { delete intermediatePointList; return; } // copying to a grid vigra::copyImage(srcImageRange(intermediateImg), vigra_ext::stride(2, 2, vigra_ext::apply(gBB, destImage(intermediateGraphImg)))); // calculating differences between pixels that are adjacent in the original image convolveImage(srcImageRange(intermediateGraphImg), destImage(graphImg), vigra::kernel2d(edgeWeightKernel)); vigra::copyImage(srcImageRange(graphImg), destImage(intermediateGraphImg)); #ifdef DEBUG_GRAPHCUT exportImage(srcImageRange(intermediateImg), ImageExportInfo("./debug/diff.tif").setPixelType("UINT8")); exportImage(srcImageRange(intermediateGraphImg), ImageExportInfo("./debug/diff2.tif").setPixelType("UINT8")); exportImage(mask1_upperleft, mask1_lowerright, ma1, ImageExportInfo("./debug/mask1.tif").setPixelType("UINT8")); exportImage(mask2_upperleft, mask2_upperleft + masksize, ma2, ImageExportInfo("./debug/mask2.tif").setPixelType("UINT8")); exportImage(src1_upperleft, src1_lowerright, sa1, ImageExportInfo("./debug/src1.tif").setPixelType("UINT8")); exportImage(src2_upperleft, src2_upperleft + size, sa2, ImageExportInfo("./debug/src2.tif").setPixelType("UINT8")); exportImage(srcImageRange(gradientX), ImageExportInfo("./debug/gradx.tif").setPixelType("UINT8")); exportImage(srcImageRange(gradientY), ImageExportInfo("./debug/grady.tif").setPixelType("UINT8")); exportImage(srcImageRange(graphImg), ImageExportInfo("./debug/graph.tif").setPixelType("UINT8")); #endif // a set of points to keep visited points for subsequent graph-cut runs std::unordered_set visited; // find optimal cuts in dual graph for (std::vector::iterator i = intermediatePointList->begin(); i != intermediatePointList->end(); ++i) { if (i == intermediatePointList->begin()) { intermediatePoint = *i; continue; } srcDestPoints.clear(); srcDestPoints.top.insert(intermediatePoint); srcDestPoints.bottom.insert(*i); #ifdef DEBUG_GRAPHCUT std::cout << "Running graph-cut: " << intermediatePoint << ":" << *i << std::endl; #endif dualPath = A_star, IMAGETYPE, BasePixelType> (vigra::Point2D(-10, -10), vigra::Point2D(-20, -20), &intermediateGraphImg, &gradientX, &gradientY, graphsize - vigra::Diff2D(1, 1), &srcDestPoints, &visited); visited.insert(dualPath->begin(), dualPath->end()); for (std::vector::reverse_iterator j = dualPath->rbegin(); j < dualPath->rend(); j++) { if ((j == dualPath->rbegin() && totalDualPath.empty()) || j != dualPath->rbegin()) { totalDualPath.push_back(*j); } } vigra::copyImage(srcImageRange(graphImg), destImage(intermediateGraphImg)); intermediatePoint = *i; } processCutResults (mask1_upperleft, mask1_lowerright, ma1, mask2_upperleft, ma2, dest_upperleft, da, totalDualPath, iBB); delete intermediatePointList; delete dualPath; } } /* namespace enblend */ #endif /* GRAPHCUT_H */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/opencl_exposure_weight.h0000644000175000017500000000275712641706002016724 00000000000000/* * Copyright (C) 2015, 2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OPENCL_EXPOSURE_WEIGHT_INCLUDED #define OPENCL_EXPOSURE_WEIGHT_INCLUDED #include #include "exposure_weight_base.h" namespace opencl_exposure_weight { bool is_opencl_file(const std::string& a_source_file_name); ExposureWeight* make_weight_function(const std::string& a_source_file_name, ExposureWeight::argument_const_iterator some_arguments_begin, ExposureWeight::argument_const_iterator some_arguments_end, double a_y_optimum, double a_width); } // namespace opencl_exposure_weight #endif // OPENCL_EXPOSURE_WEIGHT_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/exposure_weight_base.h0000644000175000017500000000467212672731617016372 00000000000000/* * Copyright (C) 2013-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. */ #ifndef EXPOSURE_WEIGHT_BASE_INCLUDED #define EXPOSURE_WEIGHT_BASE_INCLUDED #include #include #include #include // Version number of the interface-to-user-weight functions. #define EXPOSURE_WEIGHT_INTERFACE_VERSION 2 // The full width at half of the maximum of the Gauss-curve we use for // exposure weighting is // FWHM = 2 * sqrt(2 * log(2)) // For compatibility in the sake of least surprise of the user, all // other exposure weight functions rescale their native FWHM to match // the Gauss-curve. #define FWHM_GAUSSIAN 2.3548200450309493820231386529193992755 class ExposureWeight { public: typedef std::vector argument_list_t; typedef argument_list_t::const_iterator argument_const_iterator; ExposureWeight() : y_optimum_(0.5), width_(0.2) {} ExposureWeight(double y_optimum, double width_parameter) : y_optimum_(y_optimum), width_(width_parameter) { check_invariant(); } virtual void initialize(double y_optimum, double width_parameter, argument_const_iterator arguments_begin, argument_const_iterator arguments_end) { y_optimum_ = y_optimum; width_ = width_parameter; arguments_.clear(); std::copy(arguments_begin, arguments_end, std::back_inserter(arguments_)); check_invariant(); } double optimum() const {return y_optimum_;} double width() const {return width_;} const argument_list_t& arguments() const {return arguments_;} virtual double normalize(double y) const {return (y - optimum()) / width();} virtual double weight(double) = 0; virtual ~ExposureWeight() {} struct error : public std::runtime_error { error(const std::string& message) : std::runtime_error(message) {} }; virtual int interface_version() const {return EXPOSURE_WEIGHT_INTERFACE_VERSION;} private: void check_invariant() const { if (y_optimum_ < 0.0 || y_optimum_ > 1.0) { throw std::invalid_argument("y_optimum"); } if (width_ <= 0.0) { throw std::invalid_argument("width_parameter"); } } double y_optimum_; double width_; argument_list_t arguments_; }; #endif // EXPOSURE_WEIGHT_BASE_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/fillpolygon.hxx0000644000175000017500000004063012641706002015051 00000000000000/* * Copyright (C) 2012-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FILLPOLYGON_HXX #define FILLPOLYGON_HXX #include #include #include #include #include #include #ifndef HAVE_LRINT __inline long int lrint (double x){ return static_cast(x + (x < 0.0 ? -0.5 : 0.5)); } #endif #define END_OF_SEGMENT_MARKER vigra::Point2D(INT_MIN, INT_MIN) namespace vigra_ext { namespace detail { template inline static vigra::Rect2D get_polygon_extent(PolygonVertexIterator vertex_begin, PolygonVertexIterator vertex_end) { if (vertex_begin == vertex_end) { throw std::invalid_argument("empty polygon"); } int left = vertex_begin->px(); int top = vertex_begin->py(); int right = vertex_begin->px(); int bottom = vertex_begin->py(); for (PolygonVertexIterator v = vertex_begin; v != vertex_end; ++v) { if (*v != END_OF_SEGMENT_MARKER) { left = std::min(left, v->px()); top = std::min(top, v->py()); right = std::max(right, v->px()); bottom = std::max(bottom, v->py()); } } return vigra::Rect2D(left, top, right, bottom); } typedef enum {HORIZONTAL_LEFT, CROSSING, TOUCHING, HORIZONTAL_RIGHT} intersection_t; inline static intersection_t intersection_of_bool(bool is_touching) { return is_touching ? TOUCHING : CROSSING; } inline static bool is_touching_point(const vigra::Point2D& u, const vigra::Point2D& v, int y) { return (u.py() >= y && v.py() >= y) || (u.py() < y && v.py() < y); } template inline void search_intersections(const PolygonVertexIterator& vertex_begin, const PolygonVertexIterator& vertex_end, int y, // y-coordinate of scanline BackInsertIterator intersections_end) { if (vertex_begin == vertex_end) { return; } PolygonVertexIterator u(vertex_begin); PolygonVertexIterator v(vertex_begin); ++v; while (v != vertex_end) { if (*u != END_OF_SEGMENT_MARKER && *v != END_OF_SEGMENT_MARKER) { const int delta_y = v->py() - u->py(); if (delta_y != 0) { const double m = static_cast(y - u->py()) / static_cast(delta_y); if (0.0 <= m && m <= 1.0) { const int x = lrint(static_cast(u->px()) + m * static_cast(v->px() - u->px())); *intersections_end++ = std::make_pair(x, intersection_of_bool(is_touching_point(*u, *v, y))); } } else if (y == u->py()) // horizontal segment in _current_ scanline { *intersections_end++ = std::make_pair(std::min(u->px(), v->px()), HORIZONTAL_LEFT); *intersections_end++ = std::make_pair(std::max(u->px(), v->px()), HORIZONTAL_RIGHT); } } ++u; ++v; } } template inline void search_intersections_active(ActiveList& active_segments, int y, // y-coordinate of scanline BackInsertIterator intersections_end) { typedef typename ActiveList::iterator active_list_iterator; active_list_iterator a(active_segments.begin()); while (a != active_segments.end()) { if (a->first != END_OF_SEGMENT_MARKER && a->second != END_OF_SEGMENT_MARKER) { const int delta_y = a->second.py() - a->first.py(); if (delta_y != 0) { const double m = static_cast(y - a->first.py()) / static_cast(delta_y); if (0.0 <= m && m <= 1.0) { const int x = lrint(static_cast(a->first.px()) + m * static_cast(a->second.px() - a->first.px())); *intersections_end++ = std::make_pair(x, intersection_of_bool(is_touching_point(a->first, a->second, y))); if (m == 1.0) { active_segments.erase(a++); // see: Meyers, Effective STL, Item 9 continue; } } } else if (y == a->first.py()) // horizontal segment in _current_ scanline { *intersections_end++ = std::make_pair(std::min(a->first.px(), a->second.px()), HORIZONTAL_LEFT); *intersections_end++ = std::make_pair(std::max(a->first.px(), a->second.px()), HORIZONTAL_RIGHT); } } ++a; } } template inline static void fill_row(const RowIterator& row, int x_first, int x_last, Accessor accessor, const typename Accessor::value_type& value) { for (int x = x_first; x <= x_last; ++x) { accessor.set(value, row, x); } } template inline static T limit(T x, T lower_limit, T upper_limit) { return std::min(std::max(x, lower_limit), upper_limit); } struct malformed_polygon : public std::runtime_error { malformed_polygon(const std::string& message) : std::runtime_error(message) {} }; template inline static void fill_row_segments(const IntersectionList& intersections, const RowIterator& row, int row_width, Accessor accessor, const typename Accessor::value_type& value) { typedef typename IntersectionList::size_type size_type; const size_type n = intersections.size(); const int row_max = row_width - 1; if (n >= 2U && n % 2U == 0U) { for (size_type i = 0U; i != n; i += 2U) { const int x0 = limit(intersections[i], 0, row_max); const int x1 = limit(intersections[i + 1], 0, row_max); detail::fill_row(row, x0, x1, accessor, value); } } else { throw malformed_polygon("vigra_ext::fill_row_segments: open polygon"); } } template void group_to_pairs(Iterator begin, Iterator end, BackInsertIterator result) { typedef typename Iterator::value_type value_type; typedef std::vector array; typedef typename array::const_iterator array_const_iterator; array horizontal_begins; array horizontal_ends; for (Iterator i = begin; i != end; ++i) { switch (i->second) { case TOUCHING: *result++ = i->first; BOOST_FALLTHROUGH; case CROSSING: *result++ = i->first; break; case HORIZONTAL_LEFT: horizontal_begins.push_back(i->first); break; case HORIZONTAL_RIGHT: horizontal_ends.push_back(i->first); break; default: NEVER_REACHED("unknown intersection_t"); } } assert(horizontal_begins.size() == horizontal_ends.size()); array_const_iterator x0(horizontal_begins.begin()); array_const_iterator x1(horizontal_ends.begin()); while (x0 != horizontal_begins.end()) { *result++ = *x0++; *result++ = *x1++; } } template struct LessThanSegment : public std::binary_function { bool operator()(const SegmentType& s, const SegmentType& t) const { const int s_min_y = std::min(s.first.py(), s.second.py()); const int t_min_y = std::min(t.first.py(), t.second.py()); if (s_min_y < t_min_y) { return true; } else if (s_min_y == t_min_y) { const int s_min_x = std::min(s.first.px(), s.second.px()); const int t_min_x = std::min(t.first.px(), t.second.px()); return s_min_x < t_min_x; } else { return false; } } }; } // end namespace detail template void fill_polygon(const ImageIterator& upper_left, const ImageIterator& lower_right, const ImageAccessor& accessor, const PolygonVertexIterator& vertex_begin, const PolygonVertexIterator& vertex_end, const ValueType& fill_value) { typedef std::pair intersection_data; typedef std::vector intersection_list; typedef typename ImageIterator::row_iterator row_iterator; if (vertex_begin == vertex_end) { return; } const vigra::Size2D image_size(lower_right - upper_left); const vigra::Rect2D extent(detail::get_polygon_extent(vertex_begin, vertex_end)); #ifdef DEBUG_POLYGON_FILL std::cout << "+ fill_polygon: image's size = " << image_size << "\n" << "+ fill_polygon: polygon's extent = " << extent; unsigned i = 0U; for (PolygonVertexIterator v = vertex_begin; v != vertex_end; ++v) { if (i % 5U == 0U) { std::cout << "\n+ fill_polygon: vertices "; } else { std::cout << " "; } if (*v == END_OF_SEGMENT_MARKER) { std::cout << ""; } else { std::cout << *v; } ++i; } std::cout << "\n"; #endif #ifdef OPENMP #pragma omp for #endif for (int y = std::max(0, extent.top()); y < std::min(image_size.height(), extent.bottom()); ++y) { intersection_list intersections; detail::search_intersections(vertex_begin, vertex_end, y, std::back_inserter(intersections)); if (!intersections.empty()) // OPTIMIZATION: skip empty scanlines { std::sort(intersections.begin(), intersections.end()); std::vector paired_intersections; paired_intersections.reserve(intersections.size()); detail::group_to_pairs(intersections.begin(), intersections.end(), std::back_inserter(paired_intersections)); const row_iterator row((upper_left + vigra::Diff2D(0, y)).rowIterator()); detail::fill_row_segments(paired_intersections, row, image_size.width(), accessor, fill_value); } } } template void fill_polygon_active(const ImageIterator& upper_left, const ImageIterator& lower_right, const ImageAccessor& accessor, const PolygonVertexIterator& vertex_begin, const PolygonVertexIterator& vertex_end, const ValueType& fill_value) { typedef std::pair intersection_data; typedef std::vector intersection_list; typedef typename ImageIterator::row_iterator row_iterator; if (vertex_begin == vertex_end) { return; } const vigra::Size2D image_size(lower_right - upper_left); const vigra::Rect2D extent(detail::get_polygon_extent(vertex_begin, vertex_end)); typedef std::pair segment; typedef std::vector segments; typedef typename segments::const_iterator segments_const_iterator; typedef std::list segment_list; // Create the line segments that make up the polygon. We sort the // y-coordinates ascendingly. segments polygon_segments; PolygonVertexIterator u(vertex_begin); PolygonVertexIterator v(vertex_begin); ++v; while (v != vertex_end) { polygon_segments.push_back(u->py() < v->py() ? std::make_pair(*u, *v) : std::make_pair(*v, *u)); ++u; ++v; } // Sort the line segments according to their y-coordinates. std::sort(polygon_segments.begin(), polygon_segments.end(), detail::LessThanSegment()); segment_list active_segments; segments_const_iterator s(polygon_segments.begin()); #ifdef OPENMP #pragma omp parallel for private (active_segments) firstprivate (s) #endif for (int y = std::max(0, extent.top()); y < std::min(image_size.height(), extent.bottom()); ++y) { // Fill active-segments range. while (s != polygon_segments.end() && s->first.py() <= y) { // NOTE: In the parallel version all threads start at // polygon_segments.begin(), but we need to record // only segments that reach beyond our scan-line. if (s->second.py() >= y) { active_segments.push_back(*s); } ++s; } intersection_list intersections; detail::search_intersections_active(active_segments, y, std::back_inserter(intersections)); if (!intersections.empty()) // OPTIMIZATION: skip empty scanlines { std::sort(intersections.begin(), intersections.end()); std::vector paired_intersections; paired_intersections.reserve(intersections.size()); detail::group_to_pairs(intersections.begin(), intersections.end(), std::back_inserter(paired_intersections)); const row_iterator row((upper_left + vigra::Diff2D(0, y)).rowIterator()); detail::fill_row_segments(paired_intersections, row, image_size.width(), accessor, fill_value); } } } } // end namespace vigra_ext #endif // FILLPOLYGON_HXX enblend-enfuse-4.2/src/alternativepercentage.cc0000644000175000017500000000275312641706002016651 00000000000000/* * Copyright (C) 2015-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "alternativepercentage.h" AlternativePercentage::AlternativePercentage(double a_value, bool is_percentage) : value_(a_value), is_percentage_(is_percentage) {} void AlternativePercentage::set_value(double a_value) { value_ = a_value; } void AlternativePercentage::set_percentage(bool is_percentage) { is_percentage_ = is_percentage; } std::string AlternativePercentage::str() const { std::ostringstream oss; oss << value_; if (is_percentage_) { oss << "%"; } return oss.str(); } CompactifiedAlternativePercentage::CompactifiedAlternativePercentage(double a_value, bool is_percentage) : AlternativePercentage(a_value, is_percentage) {} enblend-enfuse-4.2/src/opencl_exposure_weight.cc0000644000175000017500000004216712674451223017071 00000000000000/* * Copyright (C) 2015, 2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include // std::for_each #include #include // std::lround #include // std::time_t, std::time() #include // std::ifstream #include #include #include "opencl.h" #include "parameter.h" #include "opencl_exposure_weight.h" extern const std::string command; #ifdef OPENCL extern cl::Context* GPUContext; #endif namespace opencl_exposure_weight { bool is_opencl_file(const std::string& a_source_file_name) { const std::string::size_type size = a_source_file_name.size(); return size >= 3 && (a_source_file_name.rfind(".cl") == size - 3 || a_source_file_name.rfind(".CL") == size - 3); } #ifdef OPENCL class UserWeightFunction : public ocl::BuildableFunction { static const std::string header_code; static const std::string kernel_code; public: UserWeightFunction() = delete; explicit UserWeightFunction(const cl::Context& a_context) : context_(a_context), f_(nullptr), preferred_work_group_size_multiple_(0U), work_group_size_(0U) {} virtual ~UserWeightFunction() { delete f_; } std::string user_code; void build(const std::string& a_build_option) { delete f_; f_ = new ocl::LazyFunctionCXXOfString(context_, header_code + user_code + kernel_code); f_->add_build_option("-cl-single-precision-constant"); f_->add_build_option("-DENFUSE_FWHM_GAUSSIAN=%.6ff", FWHM_GAUSSIAN); switch (f_->vendor_id()) { case ocl::vendor::amd: f_->add_build_option("-g"); break; case ::ocl::vendor::apple: break; case ocl::vendor::nvidia: f_->add_build_option("-cl-nv-verbose"); break; case ocl::vendor::unknown: break; } try { #ifdef DEBUG_OPENCL std::cout << "\n+ UserWeightFunction::build: by request\n\n"; #endif f_->build(a_build_option); #ifdef DEBUG_OPENCL std::cout << "+ UserWeightFunction::build: log begin ================\n" << f_->build_log() << "\n+ UserWeightFunction::build: log end ================\n" << std::endl; #endif } catch (ocl::runtime_error& an_error) { std::cerr << command << ": " << ocl::string_of_error_code(an_error.error().err()) << "\n"; std::vector messages = ocl::split_string(an_error.additional_message(), '\n', true); for (auto m : messages) { std::cerr << command << ": note: " << m << "\n"; } exit(1); } initialize(); } void wait() { f_->wait(); #ifdef DEBUG_OPENCL std::cerr << "\n+ UserWeightFunction::wait: carry on...\n\n"; #endif initialize(); } void initialize() { if (work_group_size_ > 0U) // initialize only once { return; } weight_kernel_ = f_->create_kernel("enfuse_user_weight_kernel"); weight_kernel_.getWorkGroupInfo(f_->device(), CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, &preferred_work_group_size_multiple_); size_t device_max_group_size; f_->device().getInfo(CL_DEVICE_MAX_WORK_GROUP_SIZE, &device_max_group_size); size_t kernel_group_size; weight_kernel_.getWorkGroupInfo(f_->device(), CL_KERNEL_WORK_GROUP_SIZE, &kernel_group_size); work_group_size_ = std::min(device_max_group_size, kernel_group_size); } size_t work_group_size() const { assert(work_group_size_ > 0U); return work_group_size_; } size_t work_group_size(size_t a_suggested_work_group_size) const { assert(work_group_size_ > 0U); return ocl::round_up_to_next_multiple(a_suggested_work_group_size, preferred_work_group_size_multiple_); } template void evaluate(random_iterator luminances_begin, random_iterator luminances_end, output_iterator some_weights) { const size_t size = luminances_end - luminances_begin; const size_t raw_size = size * sizeof(float); cl::Buffer luminance_buffer(context_, CL_MEM_READ_ONLY, raw_size); cl::Buffer weight_buffer(context_, CL_MEM_READ_WRITE, raw_size); const size_t group_size = work_group_size(32U); const size_t n = size / group_size; #ifdef DEBUG_OPENCL const size_t m = size % group_size; std::cout << "+ UserWeightFunction::evaluate: size = " << size << " -> raw-size = " << raw_size << "\n" << "+ UserWeightFunction::evaluate: work_group_size_ = " << work_group_size_ << "\n" << "+ UserWeightFunction::evaluate: group_size = " << group_size << "\n" << "+ UserWeightFunction::evaluate: n = " << n << ", m = " << m << std::endl; #endif weight_kernel_.setArg(0U, static_cast(size)); weight_kernel_.setArg(1U, luminance_buffer); weight_kernel_.setArg(2U, weight_buffer); cl::CommandQueue& queue = f_->queue(); { ocl::ScopedWriteMap luminance_map(queue, luminance_buffer, CL_TRUE, 0U, raw_size); float* ys = luminance_map.get(); for (random_iterator lumi = luminances_begin; lumi != luminances_end; ++lumi) { *ys++ = static_cast(*lumi); } } std::vector done_with_kernels(n); for (size_t i = 0U; i != n; ++i) { queue.enqueueNDRangeKernel(weight_kernel_, cl::NDRange(i * group_size), cl::NDRange(group_size), cl::NullRange, nullptr, &done_with_kernels[i]); DEBUG_CHECK_OPENCL_EVENT(done_with_kernels[i]); } cl::Event::waitForEvents(done_with_kernels); { ocl::ScopedReadMap weight_map(queue, weight_buffer, CL_TRUE, 0U, raw_size); const float* const weights = weight_map.get(); for (size_t j = 0U; j != size; ++j) { *some_weights++ = static_cast(weights[j]); } } } private: cl::Context context_; ocl::LazyFunctionCXXOfString* f_; cl::Kernel weight_kernel_; size_t preferred_work_group_size_multiple_; size_t work_group_size_; }; // class UserWeightFunction const std::string UserWeightFunction::header_code = "#line 1 \"ENFUSE-INTERNAL-HEADER\"\n" "float\n" "enfuse_normalized_luminance(float y)\n" "{\n" " return (y - ENFUSE_OPTIMUM_Y) / ENFUSE_WIDTH;\n" "}\n" "\n" "\n" "float ENFUSE_USER_WEIGHT_FUNCTION(float);\n" "\n" "\n"; const std::string UserWeightFunction::kernel_code = "\n" "\n" "#line 1 \"ENFUSE-INTERNAL-KERNEL\"\n" "kernel void\n" "enfuse_user_weight_kernel(const int n,\n" " global const float *y,\n" " global float *w)\n" "{\n" " const int i = get_global_id(0);\n" "\n" " if (i < n)\n" " {\n" " w[i] = ENFUSE_USER_WEIGHT_FUNCTION(y[i]);\n" " }\n" "}\n" "\n" "\n"; class OpenCLUserExposureWeight : public ExposureWeight { enum {OPENCL_USER_WEIGHT_SAMPLES = 32U}; public: OpenCLUserExposureWeight() = delete; OpenCLUserExposureWeight(const std::string& source_file_name, const std::string& weight_function_name) : ExposureWeight(0.5, 0.25), source_file_name_(source_file_name), weight_function_name_(weight_function_name), user_weight_function_(ocl::create_function(GPUContext)), number_of_samples_(parameter::as_unsigned("opencl-user-weight-samples", OPENCL_USER_WEIGHT_SAMPLES)) {} OpenCLUserExposureWeight(const std::string& source_file_name, const std::string& weight_function_name, double y_optimum, double width) : ExposureWeight(y_optimum, width), source_file_name_(source_file_name), weight_function_name_(weight_function_name), user_weight_function_(ocl::create_function(GPUContext)), number_of_samples_(parameter::as_unsigned("opencl-user-weight-samples", OPENCL_USER_WEIGHT_SAMPLES)) {} void initialize(double y_optimum, double width_parameter, ExposureWeight::argument_const_iterator arguments_begin, ExposureWeight::argument_const_iterator arguments_end) override { std::ostringstream build_options; for (auto p : ocl::construct_search_path()) { #ifdef _WIN32 #define PATHS_DELIMITER ';' #else #define PATHS_DELIMITER ':' #endif for (auto d : ocl::split_string(p, PATHS_DELIMITER)) { build_options << "-I" << d << " "; } } build_options << "-DENFUSE_USER_WEIGHT_FUNCTION=" << weight_function_name_ << " " << "-DENFUSE_OPTIMUM_Y=" << y_optimum << "f " << "-DENFUSE_WIDTH=" << width_parameter << "f "; std::for_each(arguments_begin, arguments_end, [&] (const std::string& x) {build_options << "-D" << x << " ";}); { std::ostringstream user_code; if (parameter::as_boolean("consult-opencl-user-exposure-weight-file", true)) { user_code << "#line 1 \"" << source_file_name_ << "\"\n" << ocl::consult_file(source_file_name_); } else { // Implementation Note: We put an ever-changing // time-stamp into the source code to trick the // OpenCL build-system into re-compiling. // // Usually the build-system is dependency // agnostic, i.e. it will not recompile if the // contents of `source_file_name_' changes. const std::time_t now(std::time(nullptr)); user_code << "#define ENFUSE_TIME_STAMP " << now << "\n" << "#include \"" << source_file_name_ << "\"\n"; } user_weight_function_->user_code = user_code.str(); } #ifdef DEBUG_OPENCL std::cout << "+ OpenCLUserExposureWeight::initialize\n" << "+ source_file_name_ = <" << source_file_name_ << ">\n" << "+ weight_function_name_ = <" << weight_function_name_ << ">\n" << "+ build-options = <" << build_options.str() << ">\n"; std::for_each(arguments_begin, arguments_end, [&] (const std::string& x) { std::cout << "+ argument: " << x << "\n";}); #endif user_weight_function_->build(build_options.str()); user_weight_function_->wait(); evaluate(); } template void generate_interval_decomposition(random_iterator first, random_iterator last) { const size_t n = last - first - 1U; const double delta = 1.0 / static_cast(n); size_t i = 0U; while (first != last) { *first++ = static_cast(i++) * delta; } } void evaluate() { number_of_samples_ = user_weight_function_->work_group_size(number_of_samples_); std::vector luminances(number_of_samples_); generate_interval_decomposition(luminances.begin(), luminances.end()); weight_samples_.clear(); user_weight_function_->evaluate(luminances.begin(), luminances.end(), std::back_inserter(weight_samples_)); #ifdef DEBUG_OPENCL for (size_t i = 0U; i != weight_samples_.size(); ++i) { std::cout << "+ OpenCLUserExposureWeight::evaluate: Y[" << i << "] = " << luminances[i] << "\t" << "w[" << i << "] = " << weight_samples_[i] << "\n"; } #endif } double weight(double y) override { assert(y >= 0.0); assert(y <= 1.0); return weight_samples_[std::lround(y * static_cast(number_of_samples_ - 1))]; } private: std::string source_file_name_; std::string weight_function_name_; std::unique_ptr user_weight_function_; size_t number_of_samples_; std::vector weight_samples_; }; // class OpenCLUserExposureWeight ExposureWeight* make_weight_function(const std::string& a_source_file_name, ExposureWeight::argument_const_iterator some_arguments_begin, ExposureWeight::argument_const_iterator some_arguments_end, double a_y_optimum, double a_width) { if (some_arguments_begin == some_arguments_end) { // Remember that built-in exposure-weight functions never // take any arguments. std::cerr << command << ": unknown built-in exposure weight function \"" << a_source_file_name << "\"" << std::endl; exit(1); } else { ExposureWeight* weight_object = nullptr; try { const std::string weight_function_name = *some_arguments_begin; if (!GPUContext) { throw std::runtime_error("cannot compile OpenCL user-weight function: GPU not enabled"); } weight_object = new OpenCLUserExposureWeight(a_source_file_name, weight_function_name); weight_object->initialize(a_y_optimum, a_width, std::next(some_arguments_begin), some_arguments_end); } catch (cl::Error& an_error) { std::cerr << command << ": " << ocl::string_of_error_code(an_error.err()) << "\n"; exit(1); } catch (ocl::runtime_error& an_error) { std::cerr << command << ": " << ocl::string_of_error_code(an_error.error().err()) << "\n"; std::vector messages = ocl::split_string(an_error.additional_message(), '\n', true); for (auto m : messages) { std::cerr << command << ": note: " << m << "\n"; } exit(1); } catch (ExposureWeight::error& an_exception) { std::cerr << command << ": user-defined OpenCL weight function \"" << "???" << "\" defined in source file \"" << a_source_file_name << "\" raised exception: " << an_exception.what() << std::endl; exit(1); } return weight_object; } } #endif // OPENCL } // namespace opencl_exposure_weight enblend-enfuse-4.2/src/exposure_weight.h0000644000175000017500000000773212641706002015362 00000000000000/* * Copyright (C) 2013-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef EXPOSURE_WEIGHT_INCLUDED #define EXPOSURE_WEIGHT_INCLUDED #ifdef _MSC_VER #define _USE_MATH_DEFINES #include #else #include #endif #include "exposure_weight_base.h" namespace exposure_weight { ExposureWeight* make_weight_function(const std::string& name, ExposureWeight::argument_const_iterator arguments_begin, ExposureWeight::argument_const_iterator arguments_end, double y_optimum, double width); void dump_weight_function(ExposureWeight* weight_function, int n); typedef enum {OK, NEGATIVE, NON_UNIT, DEGENERATE} weight_function_check_t; weight_function_check_t check_weight_function(ExposureWeight* weight_function, int n = 65536); struct Gaussian : public ExposureWeight { Gaussian(double y_optimum, double width_parameter) : ExposureWeight(y_optimum, width_parameter) {} double weight(double y) override { const double z = normalize(y); return exp(-0.5 * z * z); } }; struct Lorentzian : public ExposureWeight { // FWHM = 2 * sqrt(2) #define FWHM_LORENTZIAN 2.8284271247461900976033774484193961571 Lorentzian(double y_optimum, double width_parameter) : ExposureWeight(y_optimum, width_parameter * FWHM_GAUSSIAN / FWHM_LORENTZIAN) {} double weight(double y) override { const double z = normalize(y); return 1.0 / (1.0 + 0.5 * z * z); } }; struct HalfSinusodial : public ExposureWeight { // FWHM = 2 * arccos(1/2) #define FWHM_HALFSINUSODIAL 2.0943951023931954923084289221863352561 HalfSinusodial(double y_optimum, double width_parameter) : ExposureWeight(y_optimum, width_parameter * FWHM_GAUSSIAN / FWHM_HALFSINUSODIAL) {} double weight(double y) override { const double z = normalize(y); return fabs(z) <= M_PI_2 ? cos(z) : 0.0; } }; struct FullSinusodial : public ExposureWeight { // FWHM = pi #define FWHM_FULLSINUSODIAL M_PI FullSinusodial(double y_optimum, double width_parameter) : ExposureWeight(y_optimum, width_parameter * FWHM_GAUSSIAN / FWHM_FULLSINUSODIAL) {} double weight(double y) override { const double z = normalize(y); return fabs(z) <= M_PI ? 0.5 + cos(z) / 2.0 : 0.0; } }; struct Bisquare : public ExposureWeight { // FWHM = 2 / sqrt(sqrt(2)) #define FWHM_BISQUARE 1.6817928305074290860622509524664297901 Bisquare(double y_optimum, double width_parameter) : ExposureWeight(y_optimum, width_parameter * FWHM_GAUSSIAN / FWHM_BISQUARE) {} double weight(double y) override { const double z = normalize(y); if (fabs(z) <= 1.0) { const double z2 = z * z; return (1.0 - z2) * (1.0 + z2); } else { return 0.0; } } }; } // namespace exposure_weight #endif // EXPOSURE_WEIGHT_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/minimizer.h0000644000175000017500000002124312673533541014150 00000000000000/* * Copyright (C) 2012-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef MINIMIZER_H_INCLUDED #define MINIMIZER_H_INCLUDED #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include class Minimizer { enum {ITERATIONS_PER_DIMENSION = 100U}; public: Minimizer() = delete; explicit Minimizer(size_t a_dimension); Minimizer(const Minimizer& a_minimizer); Minimizer& operator=(const Minimizer& a_minimizer); virtual ~Minimizer() {} virtual std::string proper_name() const = 0; size_t dimension() const {return dimension_;} void set_dimension(size_t a_dimension) {dimension_ = a_dimension;} Minimizer* set_maximum_number_of_iterations(unsigned n); Minimizer* unset_maximum_number_of_iterations(); unsigned number_of_iterations() const {return iteration_;} void next_iteration() {++iteration_;} Minimizer* set_goal(double a_goal); Minimizer* unset_goal(); Minimizer* set_absolute_error(double absolute_error); Minimizer* unset_absolute_error(); virtual double f_minimum() const = 0; virtual bool has_reached_goal() const; virtual bool has_reached_maximum_iteration() const; struct minimum_not_bracketed : public std::runtime_error { minimum_not_bracketed(const std::string& a_message) : std::runtime_error(a_message) {} }; protected: virtual double absolute_error() const; private: size_t dimension_; boost::optional maximum_iteration_; unsigned iteration_; boost::optional f_goal_; boost::optional absolute_error_; }; class Minimizer1D : public Minimizer { public: Minimizer1D() = delete; Minimizer1D(const gsl_function& a_function, double x_minimum, double x_lower, double x_upper); Minimizer1D(const Minimizer1D& a_minimizer); Minimizer1D& operator=(const Minimizer1D& a_minimizer); virtual ~Minimizer1D() {gsl_min_fminimizer_free(minimizer_);} virtual std::string proper_name() const; void set_bracket(const gsl_function& a_function, double x_minimum, double x_lower, double x_upper); Minimizer1D* set_relative_error(double a_relative_error); Minimizer1D* unset_relative_error(); void run(); virtual double x_minimum() const {return x_minimum_;} virtual double f_minimum() const {return gsl_min_fminimizer_f_minimum(minimizer_);} protected: const gsl_min_fminimizer_type* type() const {return type_;} void require_ordered_x() const; void initialize(const gsl_min_fminimizer_type* a_minimizer_type); virtual double relative_error() const; virtual bool has_reached_tolerance() const; private: const gsl_min_fminimizer_type* type_; gsl_min_fminimizer* minimizer_; gsl_function function_; double x_minimum_; double x_lower_; double x_upper_; boost::optional relative_error_; }; class GoldenSectionMinimizer1D : public Minimizer1D { public: GoldenSectionMinimizer1D() = delete; GoldenSectionMinimizer1D(const gsl_function& a_function, double x_minimum, double x_lower, double x_upper); GoldenSectionMinimizer1D(const GoldenSectionMinimizer1D& a_minimizer); }; class BrentMinimizer1D : public Minimizer1D { public: BrentMinimizer1D() = delete; BrentMinimizer1D(const gsl_function& a_function, double x_minimum, double x_lower, double x_upper); BrentMinimizer1D(const BrentMinimizer1D& a_minimizer); }; class GillMurrayMinimizer1D : public Minimizer1D { public: GillMurrayMinimizer1D() = delete; GillMurrayMinimizer1D(const gsl_function& a_function, double x_minimum, double x_lower, double x_upper); GillMurrayMinimizer1D(const GillMurrayMinimizer1D& a_minimizer); }; //////////////////////////////////////////////////////////////////////// template inline static void copy_to_gsl_vector(input_iterator first, input_iterator last, gsl_vector* a_vector) { unsigned i = 0U; while (first != last) { gsl_vector_set(a_vector, i, *first); ++i; ++first; } } template inline static output_iterator copy_from_gsl_vector(gsl_vector* a_vector, output_iterator a_result) { for (unsigned i = 0U; i != a_vector->size; ++i) { *a_result = gsl_vector_get(a_vector, i); ++a_result; } return a_result; } //////////////////////////////////////////////////////////////////////// class MinimizerMultiDimensionNoDerivative : public Minimizer { public: typedef std::vector array_type; MinimizerMultiDimensionNoDerivative() = delete; MinimizerMultiDimensionNoDerivative(const gsl_multimin_function& a_function, const array_type& a_start, const array_type& some_step_sizes); MinimizerMultiDimensionNoDerivative(const gsl_multimin_function& a_function, const array_type& a_start); MinimizerMultiDimensionNoDerivative(const MinimizerMultiDimensionNoDerivative& a_minimizer); MinimizerMultiDimensionNoDerivative& operator=(const MinimizerMultiDimensionNoDerivative& a_minimizer); virtual ~MinimizerMultiDimensionNoDerivative(); void set_start(const array_type& a_start); void set_step_sizes(const array_type& some_step_sizes); template output_iterator get_step_sizes(output_iterator a_result) const { return copy_from_gsl_vector(step_sizes_, a_result); } virtual std::string proper_name() const; void run(); template output_iterator x_minimum(output_iterator a_result) const { return copy_from_gsl_vector(gsl_multimin_fminimizer_x(minimizer_), a_result); } virtual double f_minimum() const; double characteristic_size() const {return characteristic_size_;} protected: const gsl_multimin_fminimizer_type* type() const {return type_;} void initialize_step_sizes(const array_type& some_step_sizes); void set(); void initialize(const gsl_multimin_fminimizer_type* a_fminimizer_type); private: const gsl_multimin_fminimizer_type* type_; gsl_multimin_fminimizer* minimizer_; gsl_multimin_function function_; gsl_vector* xs_; gsl_vector* step_sizes_; double characteristic_size_; }; class MinimizerMultiDimensionSimplex : public MinimizerMultiDimensionNoDerivative { public: MinimizerMultiDimensionSimplex() = delete; MinimizerMultiDimensionSimplex(const gsl_multimin_function& a_function, const array_type& a_start, const array_type& some_step_sizes); MinimizerMultiDimensionSimplex(const gsl_multimin_function& a_function, const array_type& a_start); MinimizerMultiDimensionSimplex(const MinimizerMultiDimensionSimplex& a_minimizer); }; class MinimizerMultiDimensionSimplex2 : public MinimizerMultiDimensionNoDerivative { public: MinimizerMultiDimensionSimplex2() = delete; MinimizerMultiDimensionSimplex2(const gsl_multimin_function& a_function, const array_type& a_start, const array_type& some_step_sizes); MinimizerMultiDimensionSimplex2(const gsl_multimin_function& a_function, const array_type& a_start); MinimizerMultiDimensionSimplex2(const MinimizerMultiDimensionSimplex2& a_minimizer); }; class MinimizerMultiDimensionSimplex2Randomized : public MinimizerMultiDimensionNoDerivative { public: MinimizerMultiDimensionSimplex2Randomized() = delete; MinimizerMultiDimensionSimplex2Randomized(const gsl_multimin_function& a_function, const array_type& a_start, const array_type& some_step_sizes); MinimizerMultiDimensionSimplex2Randomized(const gsl_multimin_function& a_function, const array_type& a_start); MinimizerMultiDimensionSimplex2Randomized(const MinimizerMultiDimensionSimplex2Randomized& a_minimizer); }; #endif // MINIMIZER_H_INCLUDED // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/openmp_def.h0000644000175000017500000001305712662065267014270 00000000000000/* * Copyright (C) 2009-2016 Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OPENMP_DEF_H_INCLUDED_ #define OPENMP_DEF_H_INCLUDED_ #ifdef HAVE_CONFIG_H #include #endif #include // std::malloc, std::free #include #include // sig_atomic_t #if defined(HAVE_GPERFTOOLS_TCMALLOC_H) #include #elif defined(HAVE_TCMALLOC_H) #include #endif #if defined(_OPENMP) && _OPENMP >= 200203 // at least OpenMP version 2.0 #include #include "muopt.h" #define OPENMP #define OPENMP_YEAR (_OPENMP / 100) #define OPENMP_MONTH (_OPENMP % 100) #define OPENMP_PRAGMA(m_token_sequence) _Pragma(#m_token_sequence) namespace omp { #ifndef _MSC_VER inline static void* __attribute__((malloc)) malloc(size_t); #endif inline static void* malloc(size_t size) { #if defined(__ICC) #define OMP_MALLOC_FUNCTIONS "kmp_malloc/kmp_delete" return kmp_malloc(size); #elif defined(HAVE_TCMALLOC) #define OMP_MALLOC_FUNCTIONS "tc_malloc/tc_delete" return tc_malloc(size); #else #define OMP_MALLOC_FUNCTIONS "malloc/free" return ::malloc(size); #endif } inline static void free(void* pointer) { #if defined(__ICC) kmp_free(pointer); #elif defined(HAVE_TCMALLOC) tc_free(pointer); #else ::free(pointer); #endif } } // namespace omp #else #undef OPENMP #define OPENMP_YEAR 0 #define OPENMP_MONTH 0 #define OPENMP_PRAGMA(m_token_sequence) inline void omp_set_num_threads(int) {} inline int omp_get_num_threads() {return 1;} inline int omp_get_max_threads() {return 1;} inline int omp_get_thread_num() {return 0;} inline int omp_get_num_procs() {return 1;} inline void omp_set_dynamic(int) {} inline int omp_get_dynamic() {return 0;} inline int omp_in_parallel() {return 0;} inline void omp_set_nested(int) {} inline int omp_get_nested() {return 0;} #if 0 typedef enum omp_sched_t { omp_sched_static = 1, omp_sched_dynamic = 2, omp_sched_guided = 3, omp_sched_auto = 4 } omp_sched_t; inline void omp_get_schedule(omp_sched_t*, int*) {} inline void omp_set_schedule(omp_sched_t, int) {} #endif namespace omp { #ifndef _MSC_VER inline static void* __attribute__((malloc)) malloc(size_t); #endif inline static void* malloc(size_t size) { return std::malloc(size); } inline static void free(void* pointer) { std::free(pointer); } } // namespace omp #endif // _OPENMP >= 200505 // Answer whether the underlying OpenMP implementation really (thinks // that it) supports nested parallelism. inline static bool have_openmp_nested() { const int openmp_nested = omp_get_nested(); omp_set_nested(true); const bool result = omp_get_nested() != 0; omp_set_nested(openmp_nested); return result; } // Answer whether the underlying OpenMP implementation really (thinks // that it) supports dynamic adjustment of the number of threads. inline static bool have_openmp_dynamic() { const int openmp_dynamic = omp_get_dynamic(); omp_set_dynamic(true); const bool result = omp_get_dynamic() != 0; omp_set_dynamic(openmp_dynamic); return result; } namespace omp { typedef sig_atomic_t atomic_t; class scoped_nested { public: scoped_nested() : level_(omp_get_nested()) {} explicit scoped_nested(bool allow_nested) : level_(omp_get_nested()) { omp_set_nested(static_cast(allow_nested)); } ~scoped_nested() {omp_set_nested(level_);} int level() const {return level_;} private: const int level_; }; class scoped_dynamic { public: scoped_dynamic() : dynamic_(omp_get_dynamic() != 0) {} explicit scoped_dynamic(bool allow_dynamic) : dynamic_(omp_get_dynamic() != 0) { omp_set_dynamic(static_cast(allow_dynamic)); } ~scoped_dynamic() {omp_set_dynamic(dynamic_);} bool is_dynamic() const {return dynamic_;} private: const bool dynamic_; }; #if 0 class scoped_schedule { public: scoped_schedule() {initialize();} explicit scoped_schedule(omp_sched_t a_schedule) { initialize(); omp_set_schedule(a_schedule, chunk_size_); } scoped_schedule(omp_sched_t a_schedule, int a_chunk_size) { initialize(); omp_set_schedule(a_schedule, a_chunk_size); } ~scoped_schedule() {omp_set_schedule(schedule_, chunk_size_);} omp_sched_t schedule() const {return schedule_;} int chunk_size() const {return chunk_size_;} private: void initialize() {omp_get_schedule(&schedule_, &chunk_size_);} omp_sched_t schedule_; int chunk_size_; }; #endif } // namespace omp #endif // OPENMP_DEF_H_INCLUDED_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/filenameparse.h0000644000175000017500000000431312673203067014754 00000000000000/* * Copyright (C) 2009-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FILENAMEPARSE_H_INCLUDED_ #define FILENAMEPARSE_H_INCLUDED_ #include namespace enblend { /** Answer whether aFilename is specified with a relative path not * an absolute one. */ bool isRelativePath(const std::string& aFilename); /** Answer the directory part of aFilename. The function duplicates * dirname(1). */ std::string extractDirname(const std::string& aFilename); /** Answer the non-directory part of aFilename. The function * duplicates basename(1). */ std::string extractBasename(const std::string& aFilename); /** Answer the filename part of aFilename. This is the basename of * aFilename without extension. */ std::string extractFilename(const std::string& aFilename); /** Answer the extension part of aFilename including the leading * dot. */ std::string extractExtension(const std::string& aFilename); /** Answer aPathname with all superfluous "." and ".." removed. * If keepDot is true an empty path gets normalized to "." * instead of the empty string. */ std::string canonicalizePath(const std::string& aPathname, bool keepDot); /** Answer the concatenation of aPathname and anotherPathname. */ std::string concatPath(const std::string& aPathname, const std::string& anotherPathname); } // namespace enblend #endif // FILENAMEPARSE_H_INCLUDED_ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/bounds.h0000644000175000017500000001472612641706002013434 00000000000000/* * Copyright (C) 2004-2009 Andrew Mihal * Copyright (C) 2009-2016 Christoph Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __BOUNDS_H__ #define __BOUNDS_H__ #ifdef HAVE_CONFIG_H #include #endif #include "common.h" #include "parameter.h" #include "pyramid.h" namespace enblend { /** Characterize the overlap between src1 and src2. * The images may overlap completely (CompleteOverlap), * partially (PartialOverlap), * or not at all (NoOverlap). */ template Overlap inspectOverlap(SrcImageIterator src1_upperleft, SrcImageIterator src1_lowerright, SrcAccessor s1a, SrcImageIterator src2_upperleft, SrcAccessor s2a) { SrcImageIterator s1y = src1_upperleft; SrcImageIterator s2y = src2_upperleft; SrcImageIterator send = src1_lowerright; bool foundOverlap = false; bool foundDistinctS2 = false; for (; s1y.y < send.y; ++s1y.y, ++s2y.y) { SrcImageIterator s1x = s1y; SrcImageIterator s2x = s2y; for (; s1x.x < send.x; ++s1x.x, ++s2x.x) { if (s1a(s1x) && s2a(s2x)) { foundOverlap = true; } else if (s2a(s2x)) { foundDistinctS2 = true; } if (foundOverlap && foundDistinctS2) { // If we have found a pixel where there is overlap, // and also a pixel where src2 alone contributes, // then we know it's PartialOverlap and we can quit. return PartialOverlap; } } } if (foundOverlap) { return CompleteOverlap; } else { return NoOverlap; } }; // Argument object factory version. template Overlap inspectOverlap(vigra::triple src1, vigra::pair src2) { return inspectOverlap(src1.first, src1.second, src1.third, src2.first, src2.second); }; /** Determine the region-of-interest and number of blending levels to use, * given the current mask-bounding-box and intersection-bounding-box. * We also need to know if the image is a 360-degree pano so we can check * for the case that the ROI wraps around the left and right edges. */ template unsigned int roiBounds(const vigra::Rect2D& inputUnion, const vigra::Rect2D& iBB, const vigra::Rect2D& mBB, const vigra::Rect2D& uBB, vigra::Rect2D& roiBB, // roiBB is an _output_ parameter! bool wraparoundForMask) { roiBB = mBB; roiBB.addBorder(filterHalfWidth(MAX_PYRAMID_LEVELS)); if (wraparoundForMask && (roiBB.left() < 0 || roiBB.right() > uBB.right())) { // If the ROI goes off either edge of the uBB, and the uBB is // the full size of the output image, and the wraparound flag // is specified, then make roiBB the full width of uBB. roiBB.setUpperLeft(vigra::Point2D(0, roiBB.top())); roiBB.setLowerRight(vigra::Point2D(uBB.right(), roiBB.bottom())); } // ROI must not be bigger than uBB. roiBB &= uBB; if (Verbose >= VERBOSE_ROIBB_SIZE_MESSAGES) { std::cerr << command << ": info: region-of-interest bounding box: " << roiBB << std::endl; } // Verify the number of levels based on the size of the ROI. unsigned int roiShortDimension = std::min(roiBB.width(), roiBB.height()); const unsigned int minimumPyramidLevels = parameter::as_unsigned("minimum-pyramid-levels", 1U); //< minimum-pyramid-levels 1 unsigned int allowableLevels = minimumPyramidLevels; while (allowableLevels <= MAX_PYRAMID_LEVELS) { if (roiShortDimension <= 8U) { // ROI dimensions preclude using more levels than allowableLevels. break; } roiShortDimension = (roiShortDimension + 1U) >> 1; ++allowableLevels; } if (allowableLevels <= minimumPyramidLevels) { std::cerr << command << ": info: overlap region is too small to make more than " << minimumPyramidLevels << " pyramid level(s)" << std::endl; } else { if (ExactLevels >= 1) { if (ExactLevels > static_cast(allowableLevels)) { std::cerr << command << ": warning: cannot blend with " << ExactLevels << " pyramid level(s) as\n" << command << ": warning: image geometry precludes using more than " << allowableLevels << " pyramid level(s)" << std::endl; } allowableLevels = std::min(allowableLevels, static_cast(ExactLevels)); } else if (ExactLevels < 0) { if (static_cast(allowableLevels) + ExactLevels >= static_cast(minimumPyramidLevels)) { allowableLevels -= static_cast(-ExactLevels); } else { std::cerr << ": warning: cannot sensibly blend with " << allowableLevels << ExactLevels << " levels\n" << command << ": warning: will not use less than " << minimumPyramidLevels << " pyramid level(s)" << std::endl; allowableLevels = minimumPyramidLevels; } } } if (Verbose >= VERBOSE_PYRAMID_MESSAGES) { std::cerr << command << ": info: using "; if (allowableLevels == 1) { std::cerr << "single blending level"; } else { std::cerr << allowableLevels << " blending levels"; } std::cerr << std::endl; } assert(allowableLevels >= minimumPyramidLevels); assert(allowableLevels <= MAX_PYRAMID_LEVELS); return allowableLevels; } } // namespace enblend #endif /* __BOUNDS_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/src/tiff_message.cc0000644000175000017500000000572612641706002014734 00000000000000/* * Copyright (C) 2009-2016 Dr. Christoph L. Spiel * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include // fflush(), vsnprintf() #include #include #include #include #ifdef HAVE_CONFIG_H #include #endif #include "global.h" #include "tiff_message.h" extern const std::string command; extern int Verbose; static std::set tiff_messages; static std::string interpolate_format(const char* format, va_list arguments) { const size_t buffer_size = 4096U; std::string message(buffer_size, '\0'); vsnprintf(&message[0], buffer_size, format, arguments); return message; } static void flush_buffers() { fflush(stdout); std::cout.flush(); std::wcout.flush(); } /** tiff_message mangles the error and warning messages from the TIFF * library to make them look more like Enblend/Enfuse messages. * * For the messages tend to occur repeatedly, we keep track of every * message and only pass on their first appearance. The library * always includes the name of the offending TIFF file, thus we get * each message once for each file. */ static void tiff_message(const char* message_class, const char* /* module */, const char* format, va_list arguments) { const std::string message(interpolate_format(format, arguments)); if (tiff_messages.count(message) == 0) { tiff_messages.insert(message); // IMPLEMENTATION NOTE: We do not know, where we are called, // therefore we must flush all buffers before we print our // message. flush_buffers(); std::cerr << command << ": " << message_class << ": " << message << std::endl; } } void tiff_warning(const char* module, const char* format, va_list arguments) { if (Verbose >= VERBOSE_TIFF_MESSAGES) { tiff_message("warning", module, format, arguments); } } static bool is_benign(const char* format, va_list arguments) { const std::string message(interpolate_format(format, arguments)); return message == "OJPEG encoding not supported; use new-style JPEG compression instead"; } void tiff_error(const char* module, const char* format, va_list arguments) { tiff_message(is_benign(format, arguments) ? "warning" : "error", module, format, arguments); } enblend-enfuse-4.2/src/masktypedefs.h0000644000175000017500000000222612641706002014631 00000000000000/* * Copyright (C) 2011-2016 Mikolaj Leszczynski * * This file is part of Enblend. * * Enblend 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. * * Enblend 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 Enblend; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __MASKTYPEDEFS_H__ #define __MASKTYPEDEFS_H__ #include #include namespace enblend { typedef std::pair SegmentPoint; typedef std::list Segment; typedef std::vector Contour; typedef std::vector ContourVector; } #endif /* __MASKTYPEDEFS_H__ */ // Local Variables: // mode: c++ // End: enblend-enfuse-4.2/NEWS0000644000175000017500000006644312676432356011724 00000000000000* Version 4.2 Released March 29, 2016. ** Improvements - All deprecated options and features of version 4.1 have been removed. - Enblend and Enfuse support layer (aka "page", aka "frame") selection in of multi-layer image-files. This includes processing any layers in user-defined order. - Both Enblend and Enfuse can now perform all their pyramidal blending operations in CIELAB (aka L*a*b*, aka L-star) and CIELUV (aka L*u*v*) color spaces, too. See section "New Commandline Options", option `--blend-colorspace'. The previous default, CIECAM for input images with ICC-profile has been changed to CIELUV. The default for RGB images without ICC-profile remains. However, the new default for floating-point image data is to use the RGB-cube, no matter whether the images come with profiles or not. - The new Graph-Cut algorithm is the default primary seam-line generator. - Avoid a division-by-zero in the Annealing Optimizer. - Fix a bug (#1356551) in the seam-line vectorization code that was there since 2004. The fix changes the position of almost any coarse-mask seam line vertex by one pixel. - Fix a longstanding quirk, which allowed to load masks into Enblend and Enfuse that were unsuitable for processing. - Fix a bug in the highlight-recovery that caused Enfuse to bail out with the uncaught exception "Minimizer1D::set_bracket: minimum not bracketed". - The OpenMP enabled versions of Enblend and Enfuse benefit from Google's TCMalloc library. - Several exposure weight functions were added to Enfuse. The choice is now up to the user. The default still is the Gauss function as in all Enfuse versions before. ** New Commandline Options - The introduction of additional blend color spaces requires a new option to select them. The new option `--blend-colorspace' takes over the functionality of `--ciecam' and `--no-ciecam' (which both will be withdrawn in a future version) and is flexible enough for the new CIELAB and CIELUV blend color spaces. --ciecam => --blend-colorspace=CIECAM --no-ciecam => --blend-colorspace=RGBCUBE new: --blend-colorspace=CIELAB new: --blend-colorspace=CIELUV - Calling Enblend or Enfuse with `--show-software-components' will show the compiler name and version along will the versions of all important libraries against which the binaries were compiled. - The new options `--show-globbing-algorithms', `--show-image-formats', and `--show-signature' now display the information that previously was requested with `--version --verbose'. The output of `--help' has been regrouped to account for the new diversity of information options. - Option `--exposure-weight-function' makes Enfuse's exposure weight function user selectable. Previously weight function "gauss" was the only one (and hard-coded). Some examples of user-defined weight functions and a rudimentary GNUmakefile to build them get installed in DOCDIR/examples/enfuse. - The old Enfuse options `--exposure-mu' and `--exposure-sigma' got siblings called `--exposure-optimum' and `--exposure-width' respectively. With exposure weight functions other than Gauss the restricted naming does not make sense anymore. Options `--exposure-mu' and `--exposure-sigma' are scheduled for withdrawal in a later version of Enfuse. - Long-time option `-a' got a long-form sibling called `--pre-assemble'. The long form can be negated as `--no-pre-assemble', which is the default. ** Idle Commandline Options - The Stable Branch of Enblend/Enfuse does not support any acceleration with GPUs as the current Development Branch does. For commandline compatibility and easy script migration the options `--gpu', `--prefer-gpu', and `--show-gpu-info' are accepted, but do not have any functionality behind them. ** Developer Stuff - During configuration the name of Vigra's import-export library can be set with the environment variable VIGRAIMPEX_LIB. This is to splice in a library compiled with e.g. instrumentation or sanitizers. If the variable is undefined or empty the default is `-lvigraimpex', which lets most linkers prefer the dynamic library in the standard location if there is any choice. - The Automake system can be configured to print only terse messages (configure option `--enable-silent-rules'), or when working at command line level, pass `V=0' to make(1). - A C++11-compatible compiler is required to compile Enblend and Enfuse. - Support of the Boost filesystem library has been dropped. There is no Boost library dependence anymore. - Empty `--parameter' options default to "1". This behavior in conjunction with boolean parameter expansion taking "0" and "1" as aliases for "false" and "true" allows to shorten setting boolean parameters. - The new configuration option "--enable-on-demand-dynlink" controls lazy loading of all shared libraries. ** Package Maintainer Stuff - Boost version 1.55 or later is now required to build. - Vigra version 1.9 or later is now required to build. - Little CMS version 2.5 or later is now required to build. - Support for OpenGL acceleration has been dropped. So, the dependencies on the libraries GL, GLU, and Glut do not exist any longer. - Support for images with 8-bit signed channels has been dropped. - The documentation no longer uses Texinfo, but LaTeX for PostScript generation and Hevea for HTML. - fig2dev(1) of the XFig suite is no longer needed to build the documentation. All relevant images were converted to dot(1) or SVG format. * Version 4.1 "Trouble In Paradise" Released on December 8, 2012. ** Improvements - All deprecated options since version 4.0 have been removed. - A new primary seam-line generator, based on a Graph-Cut algorithm, has been implemented during GSoC 2011 by Mikołaj Leszczyński. The old Nearest-Feature Transform remains the default. The new algorithm is activated with "--primary-seam-generator=graph-cut". - The difference image on which Enblend's seam-line optimization relies for color images uses a perceptual model by default (option "--image-difference"), yielding a true CIE76 "Delta E" with the (default) luminance and chrominance weights of 1. - Parallelize CIECAM02 color conversion (option "--ciecam"). Speedups of up to 40% have been reported on the amd64 architecture. The computationally expensive color-space conversion still slows down blending and fusing by some 25%. - Enblend and Enfuse integrate seamlessly in color-managed workflow. Input images with color profiles automatically enable CIECAM blending and the output image is assigned the input images' color profile. - Enblend and Enfuse exploit a new feature in LittleCMS Version 2.x called "Unbounded CMM". Thereby, the hue and saturation of extreme shadows and highlights can be preserved much longer before pure black or white are reached. See: http://www.littlecms.com/CIC18_UnboundedCMM.pdf - Assign different profiles to profile-free input images with option "--fallback-profile" instead of being tied to sRGB. - A new gray-scale projector called "anti-value" helps when fusing with the intent of minimizing the noise in the output image. When employing a lower exposure cutoff this even is the default projector. - Both Enblend and Enfuse stop right after saving all generated masks to files, if option "--save-masks" is given, but option "--output" is not. This allows to splice tools that manipulate the masks and feed the masks back into Enblend and Enfuse with option "--load-masks". When combining option "--output" and "--save-masks" Enblend and Enfuse write all masks and the final output image as before. - Both Enblend and Enfuse can write their output JPEG files with arithmetic JPEG compression and TIFF files with JPEG compression, if the underlying JPEG and TIFF libraries support these compression schemes. ** Bug Fixes - Enblend and Enfuse consistently warn if they are passed input images that alternate between with color profile and without. - Grant SourceForge feature request ID 2991909 (OSX only). Previous to that, Enblend, when launched from a terminal window with GPU-acceleration (option "--gpu"), started a second, non-responsive terminal window and when this new Enblend window tried to "steal" the focus, it displayed the OSX rotating "beach ball". With the fix that all goes away. Also the responsiveness of the screen improves, which means that the non-functional window also hogged GUI resources. ** New Commandline Options - Option "--primary-seam-generator" controls the primary seam-line generation algorithm. - Option "--image-difference" selects the difference image calculation algorithm and optionally assigns weights to the luminance and the chrominance part of the difference image. - Short option "-c" now has a sibling called "--ciecam". The long option also has a negated form: "--no-ciecam"; the short one has not. - The option "--fallback-profile=PROFILE" allows users to pass their own profiles for image sets that come without ICC color profiles. Before the hard-coded profile was sRGB. - The option "--exposure-cutoff" facilitates tailoring the exposure weight curve specifically to exclude underexposed (and probably noisy) or overexposed pixels from fusion. - In Enblend option "--load-masks" disables all mask computations and loads the blend masks directly from the specified files. This is the dual of Enblend's long-known option "--save-masks". - The option "--layer-selector" overrides the standard default layer selector. - In addition to the usual integral values option "--levels" takes the keyword "auto", which restores the default. (The default is to automatically choose the maximum number of pyramid levels for each separate overlapping region.) ** Deprecated Features - The option "--smooth-difference" will be eliminated in the next version of Enblend; it has not helped and moreover only put lipstick on the seamline-optimizer's objective function. - The user-(re)sizable image-cache will not be available in later versions of Enblend and Enfuse. We are not sure yet whether it will be replaced by an mmap-based solution or just tossed out. ** Developer Stuff - XHTML validation does not rely on network access anymore. This means all necessary DTDs must be available locally and all catalogs must be set up correctly to build the XHTML documentation. - The option "--parameter" allows developers to pass arbitrary key-value pairs to Enblend and Enfuse. The keys must match the regular expression [A-Za-z][A-Za-z0-9_-]*; the values can be almost any string. No further checking or validation is performed. For more explanations on how to use parameters in the source code, see the block-comment within "namespace parameter" in file "common.h". ** Package Maintainer Stuff - Enblend and Enfuse now use LittleCMS version 2.x. - Enblend and Enfuse no longer rely on their own versions of the Vigra imaging library. Vigra version 1.8 or later is now required to build. - Enblend no longer relies on libXMI. (Enfuse never needed this library.) * Version 4.0 Released on December 13, 2009. ** Improvements - Huge new documentation in Info, PS, PDF, and XHTML formats. Plain HTML format is not supported because it cannot portably render MathML. - New manual pages. - Automatic bit depth conversion between input and output images if necessary. For example: given 16-bit TIFF input images and a JPEG output image Enblend and Enfuse automatically convert from 16-bit to 8-bit before writing the JPEG file. - Compilation without image cache works again ("--disable-image-cache"). Speedups of up to 30% have been reported on the amd64 architecture. - Enblend and Enfuse accept repsonse files in addition to literal image files. Response files contain lists of image filenames or names of other response files. - Lots of new warnings if a command-line option has no effect, like, for example, combining a mask optimization option with "--no-optimize". - Enblend shows the initial, unoptimized seam line in addition to the optimized one in all seam-line visualization images (option "--visualize"). - Enblend and Enfuse read multi-layer TIFF files ("multi directory" in TIFF jargon). It is even possible to mix multi-layer with single layer images. This partially fixes SourceForge bug ID 1170329. - Save masks with (lossless) "Deflate" compression. - An improved wrap-around option, formerly only "-w", now "-wMODE" and "--wrap=MODE", lets the user determine whether to create a 360 degrees horizontal or vertical panorama. It is possible to wrap around vertically and horizontally at the same time. - Without any output filename given, i.e. no "-o" option, the output filename now defaults to "a.tif", making "-o" truly an option. - The user has better control of the number of pyramid levels. Previously only the maximum number in any blend could be reduced by the "-l" option. Now, the maximum number can be reduced by a fixed amount no matter what the actual maximum number of permissible pyramid levels is. - Use OpenMP to make better use of multi-processor machines. As the image cache is not reentrant, OpenMP can only be activated when the image cache is disabled. - Enblend and Enfuse issue messages following the GNU standard. ** Bug Fixes - Fix the calculation of the number of blending levels. Previously, it was off by one in most cases. - A longstanding bug (SourceForge ID 2160427) in the primary seam line generation that caused a sub-optimal seam line was fixed. As a side effect the new seam line algorithm is at least 20% faster than the old one. - Another longstanding bug (SourceForge ID 1891785) that caused wrong output for images with holes was also fixed. - Fix a well hidden but serious bug in the seam line optimization. Both, the GPU and non-GPU versions of the optimizer were affected. - Make Enblend and Enfuse aware of the input images' resolution. Use the input resolution in the output file. With this change masks get the correct offsets. This fixes the bug that masks do not end up at the correct position with respect to the input files. - Fix MacOS problem of parsing floating-point parameters at the command line. ** New Commandline Options - All Enfuse options have been converted to Enblend's option naming scheme. This is, camel-casing has been replaced by lowercase plus dashes. The new option name are more systematically constructed, too. The old options will completely dissapear in the next release, 4.1. Old Option New Option ==================== ======================== --ContrastWindowSize --contrast-window-size --EdgeScale --contrast-edge-scale --EntropyCutoff --entropy-cutoff --EntropyWindowSize --entropy-window-size --GrayProjector --gray-projector --HardMask --hard-mask --MinCurvature --contrast-min-curvature --SaveMasks --save-masks --SoftMask --soft-mask --wContrast --contrast-weight --wEntropy --entropy-weight --wExposure --exposure-weight --wExposureMu --exposure-mu --wExposureSigma --exposure-sigma --wSaturation --saturation-weight - New option to control the output bit depth ("--depth"). - Mask filenames can be specified with templates. * Enblend ("--save-masks", "--load-masks", "--visualize"): Save and load all masks of a project in a single run. Same for seam line visualization files. * Enfuse ("--save-masks"): Save soft and hard masks according to path given in template. - New option to control the mask vectorization, which is done before any mask optimizations ("--mask-vectorize"). - New option to control the Simulated Annealing optimizer called strategy 1 ("--anneal"). - New option to control the relative weights of the distance to the initial seam line and the total mismatch ("--optimizer-weights"). - New option to control the Dijkstra path minimizer called strategy 2 ("--dijkstra"). - Option "--coarse-mask" takes an optional (linear) reduction factor. The default remains at 8. - New option "--smooth-difference" to blur difference images prior to seam-line optimization. - Long option "--levels" to control the number of levels; duplicates functionality of short option "-l". ** Removed Commandline Options - After having been deprecated for a long time, Enfuse's option "--debug", which saved the masks used in fusing, was removed. Option "--save-masks" now provides a superset of the previous functionality. - After having been deprecated for a long time, Enblend's and Enfuse's option "-z", which compressed TIFF-output files with the LZW algorithm, was removed. Option "--compression" now provides a superset of the previous functionality and "--compression=LZW" is a substitute for "-z". ** Developer Stuff - VPATH builds work. This makes it easy to compile for differently configured versions, like for example with and without image cache. - The target "make distcheck" works again. - Introduce additional Make variables to control the Make process after the project was configured. See "README" file. - Debugging of dynamic memory allocation has been eased by the integration of the DMalloc package; "configure --with-dmalloc" - Use only m4 files that clearly have a GPL license. This fixes SourceForge feature request ID 2152850. - Remove all files that are meant to be generated auto Autoconf. This fixes SourceForge bug ID 2036031. - Install m4 file to detect the M$ compiler. This fixes SourceForge bug ID 2036034. - Make "configure" report that extra features will get compiled and if they cannot tell the developer why not. - Pull version of program and documentation into file "VERSION". Both program and documentation automatically use this information on every build. - The MSVC project files were removed. They can be regenerated by the (still experimental) CMake environment. - README hosts build instructions for GNU Autoconf/Automake based systems, for MacOSX, and for Win. ** What is known not to work? - Documentation generation is not as reliable and smooth as it ought to be. The culprit is Automake; see PR/486. * Version 3.2 Released on September 8, 2008. ** Improvements - Official release of Enfuse for automatic multi-level exposure blending and focus stack creation. - Support for PNG and OpenEXR input files. - Support for writing JPEG output files (8 bit only). ** Bug Fixes - Bugfix to correctly interpret the alpha channel of float (HDR) images. ** New Commandline Options - New --compression option for selecting the compression type of the output image. ** Developer Stuff - This release includes a Windows binary that does not require a SSE2-capable processor. - There will not be a 3.1 release in order to avoid confusion with numerous cvs builds that self-identify as version 3.1. * Version 3.0 Released on January 27, 2007. ** Improvements - New, faster image processing algorithms for computing Gaussian and Laplacian pyramids. ** New Commandline Options - Optional optimization of seam line placement to try to avoid mismatches and parallax errors in the image overlap region. - Masks can now be saved and loaded from files. This makes it possible to manually edit the location of the seam before multiresolution spline blending is applied. - Checkpointing of partial results is now optional. This improves speed. - Optional blending using the CIECAM02 color appearance model. Your TIFF files should have embedded ICC profiles in order to use this option. This replaces the CIE L*a*b* color blending in Enblend 2.X that never worked properly. - Optional use of the graphics processor to speed up certain computations. This feature is experimental and may not work on all systems. ** Developer Stuff - Like other X.0 releases, please consider this a beta. * Version 2.5 Released on December 11, 2005. ** Bug Fixes - Fixed a bug where Enblend would crash when the -w parameter was used. - Fixed a bug where Enblend would sometimes say "mask transition line bounding box undefined." * Version 2.4 Released on December 3, 2005. ** Improvements - Enblend will now create output files with embedded ICC profiles. The first ICC profile found amongst the input images will be copied to the output image. Enblend does not use ICC profiles to do color calculations. - Incorporated a patch from Fulvio Senore to make the mask generation faster. Fulvio wrote a more efficient data structure for use in the nearest feature transform. ** New Commandline Options - Added support for working with cropped and shifted input images. These types of files are created by Nona's "Multiple TIFF" stitching option. A cropped and shifted TIFF saves space and time because it is just large enough for a single input image, instead of being the size of the entire output panorama with lots of empty space all around. Nona embeds an (x, y) offset coordinate in the file so that Enblend can tell where this file belongs in the final panorama. By default, if you give Enblend cropped and shifted TIFFs, the output will also be a cropped and shifted TIFF. Sometimes you may want to include the extra blank space anyway, for example if you are creating a 360-degree panorama and the image size must be exactly a 2:1 ratio. In this case, use the new -f parameter to manually set the size of the output image: -f WIDTHxHEIGHT Thanks to Pablo d'Angelo for providing this patch. * Version 2.3 Released on April 17, 2005. ** Bug Fixes - Fixed a bug in temporary file handling in the Windows version of enblend. This should solve the "unable to open temporary file" error. - Reduced the maximum number of levels you can specify with the -l parameter from 30 to 29. While both of these are impractically large, at least 29 does not lead to arithmetic overflow and a subsequent crash. - Fixed a bug in temporary file handling in the Windows version of enblend. This should solve the "unable to open temporary file" error. * Version 2.2 Released on February 5, 2004. ** Improvements - The Windows binary of Enblend is now build with a version of libtiff that includes support for all of the TIFF compression standards, such as Deflate, LZW, JPEG, and Packbits. Nona/Hugin produces TIFF files with the Deflate option. - Replaced some system calls that are specific to Windows 2000 and XP with more generic functions. This should get the Windows binary of Enblend to run on pre-Win2K machines. ** Bug Fixes - This release fixes issues with the Windows version of Enblend. If you are using Enblend on UN*X you do not need to upgrade. * Version 2.1 Released on November 15, 2004. ** Improvements - Compression is no longer the default option in the Windows executable. ** Bug Fixes - Turned off TIFF library warning messages that required user interaction on Windows. - Fixed a bug in Vigra that caused primary color spots to appear in overexposed areas of 16-bit images. - Fixed a problem with Enblend crashing on large panoramas. Modified tiff import to use a scanline-based interface instead of a strip- based interface. PTStitcher generates TIFFs with the rows/strip tag set to an unreasonable value. ** Developer Stuff - Ported the source to compile natively on Win32 using MSVC. * Version 2.0 Released on October 17, 2004. ** Improvements - Support for signed and unsigned 16-bit, 32-bit, single- and double- precision floating point pixel types. - Sophisticated memory/disk balancing. You can tell Enblend how much memory it is allowed to use, and it will swap to disk after that. - Support for huge panoramas. I have tested that Enblend can blend a 1.2 gigapixel, 16-bit per channel color image. You should be able to go right up to the 4 gigabyte limit of the TIFF format. ** Bug Fixes - Fixed the banding artifacts that often appeared in skies. ** New Commandline Options - Optional blending in CIE L*a*b* color space. - Option to use LZW compression for the output image, if your libtiff supports it. This option is selected by default in the prebuilt Windows executable. - The -s option for sequential blending is now the default. Enblend cannot accurately determine how many blending levels to use when there are multiple disjoint overlap regions in one blending iteration. It is better to manually tell Enblend the order in which the images should be blended. If you still want Enblend to assemble non-overlapping images first, use the -a flag. - The -l option now tells Enblend the exact number of blending levels that you want to use. The geometry of your images may force Enblend to use a smaller number of levels. In this case a message will be printed. - Gimp (ver. < 2) and Cinepaint exhibit unusual behaviors when loading images with unassociated alpha channels. Use the -g flag to work around this. With this flag Enblend will create the output image with the associated alpha tag set, even though the image is really unassociated alpha. ** Developer Stuff - Ported Enblend to the VIGRA Computer Vision Library. * Version 1.3 Released May 18, 2004. ** Bug Fixes - Added a configure test for the endian-ness of the machine. I changed the way enblend reads and writes 8-bit color fields in 32-bit pixel words to reflect the endian-ness of the machine. This should get enblend working on powerpc machines. This release adds no new features. * Version 1.2 Released April 26, 2004. ** Bug Fixes - Fixed a bug where 8-bit TIFFs would not be identified properly on big-endian machines. - A second (better) fix for the boundary condition problem that lead to horizontal or vertical seams to appear in the output. * Version 1.1 Released April 3, 2004. ** Bug Fixes - Fixed a bug in reading from temporary files that appeared on machines with different versions of GCC. - Fixed a boundary condition problem that lead to horizontal or vertical seams to appear in the output. - Fixed a bug where segments of an input image would appear on the far side of a blending zone. This would cause strange wedge-shaped artifacts in some output images. * Version 1.0 Released March 27, 2004. ** New Commandline Options - Added options to limit the number of blending levels used. This can reduce memory usage and improve speed, at a loss of quality. - Added an option to blend around the -180/+180 degree boundary. There is still an open issue as to how to handle the zenith and nadir. - Added an option to blend the input images sequentially in the order given on the command line. Sometimes the assembler can make poor choices and seams will still be visible in the output. ** Developer Stuff - Replaced erosive thinning algorithm for mask creation with a much faster nearest feature transform. - Reduced memory requirements. Enblend now swaps most of its data to disk as temporary files. Enblend also calculates the region of pixels that are involved in each blending step and only does math on those pixels, improving speed and memory usage. * Version 0.9 Released on March 4, 2004. Local Variables: mode: outline End: enblend-enfuse-4.2/config.h.cmake0000644000175000017500000000624212676263420013703 00000000000000/* * \file config.h * This file is part of enblend. * Licence details can be found in the file COPYING. * * This is the compilation configuration file for enblend. * You might want to change some of the defaults if something goes wrong * during the compilation. */ #ifndef _CONFIG_H #define _CONFIG_H /* Default verbosity level of Enblend and Enfuse. A value of zero reduces the message output to only warnings and errors. Values of one and more make Enblend and Enfuse report progress in detail. */ #define DEFAULT_VERBOSITY 1 ${CMAKE_HEADER_EXISTS} ${CMAKE_FUNCTION_EXISTS} /* Define to 1 if the `closedir' function returns void instead of `int'. */ #cmakedefine CLOSEDIR_VOID 1 /* Define if you have POSIX threads libraries and header files. */ #cmakedefine HAVE_PTHREAD 1 /* Define to 1 if the system has the type `ptrdiff_t'. */ #cmakedefine HAVE_PTRDIFF_T 1 /* define to 1 if you have dlfcn.h header file and dl lib. */ #cmakedefine HAVE_DL 1 /* Define to 1 if the system has the type `_Bool'. */ /* #undef HAVE__BOOL */ /* define the correct restrict keyword, Empty or one of __restrict __restrict__ _Restrict restrict */ #define RESTRICT ${RESTRICT} /* Name of package */ #define PACKAGE "enblend-enfuse" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "https://bugs.launchpad.net/enblend" /* Define to the full name of this package. */ #define PACKAGE_NAME "enblend-enfuse" /* Define to the full name and version of this package. */ #cmakedefine PACKAGE_STRING "${PACKAGE_STRING}" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "enblend-enfuse" /* Define to the version of this package. */ #define PACKAGE_VERSION "${PACKAGE_VERSION_STRING}" #define PACKAGE_URL "${PACKAGE_URL}" /* Define to necessary symbol if this constant uses a non-standard name on your system. */ /* #undef PTHREAD_CREATE_JOINABLE */ /* Define as the return type of signal handlers (`int' or `void'). */ #cmakedefine RETSIGTYPE ${RETSIGTYPE} /* Define to 1 if you have the ANSI C header files. */ #cmakedefine STDC_HEADERS 1 /* Define to 1 if strerror_r returns char *. */ #cmakedefine STRERROR_R_CHAR_P 1 /* Define to 1 if std::as_const (C++ 17) is available */ #cmakedefine HAVE_AS_CONST /* workaround for older boost versions <1.55 */ #cmakedefine HAVE_BOOST_FALLTHROUGH 1 #ifndef HAVE_BOOST_FALLTHROUGH #define BOOST_FALLTHROUGH ((void) 0) #endif /* Define to if is available */ #cmakedefine HAVE_STD_FILESYSTEM 1 /* Version number of package */ #define VERSION "${ENBLEND_VERSION_ONLY}" /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #cmakedefine WORDS_BIGENDIAN 1 /* Define to `long int' if does not define. */ #cmakedefine HAVE_OFF_T 1 #if ! defined(HAVE_OFF_T) #define off_t long int #endif /* Define to `unsigned int' if does not define. */ #cmakedefine HAVE_SIZE_T 1 #if ! defined(HAVE_SIZE_T) #define size_t unsigned int #endif /* MSVC compiler is using _DEBUG instead of DEBUG, so redefine here */ #if defined _DEBUG && !defined DEBUG #define DEBUG 1 #endif #endifenblend-enfuse-4.2/compile0000755000175000017500000001624512423346767012576 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2013 Free Software Foundation, Inc. # Written by Tom Tromey . # # 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, 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, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: enblend-enfuse-4.2/depcomp0000755000175000017500000005601612423346767012575 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2013-05-30.07; # UTC # Copyright (C) 1999-2013 Free Software Foundation, Inc. # 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, 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, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: enblend-enfuse-4.2/aclocal.m40000644000175000017500000014572412676242413013056 00000000000000# generated automatically by aclocal 1.14.1 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 1 (pkg-config-0.24) # # Copyright © 2004 Scott James Remnant . # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) # only at the first occurence in configure.ac, so if the first place # it's called might be skipped (such as if it is within an "if", you # have to call PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])# PKG_CHECK_MODULES # PKG_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable pkgconfigdir as the location where a module # should install pkg-config .pc files. By default the directory is # $libdir/pkgconfig, but the default can be changed by passing # DIRECTORY. The user can override through the --with-pkgconfigdir # parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_INSTALLDIR # PKG_NOARCH_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable noarch_pkgconfigdir as the location where a # module should install arch-independent pkg-config .pc files. By # default the directory is $datadir/pkgconfig, but the default can be # changed by passing DIRECTORY. The user can override through the # --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_NOARCH_INSTALLDIR # PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # ------------------------------------------- # Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])# PKG_CHECK_VAR # Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.14.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.14.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/_ac_latex_test.m4]) m4_include([m4/ac_latex_class.m4]) m4_include([m4/ac_latex_package.m4]) m4_include([m4/ac_prog_ar.m4]) m4_include([m4/ac_prog_latex.m4]) m4_include([m4/ac_type_sig_atomic_t.m4]) m4_include([m4/ax_boost_base.m4]) m4_include([m4/ax_cxx_as_const.m4]) m4_include([m4/ax_cxx_compile_stdcxx_11.m4]) m4_include([m4/ax_openmp.m4]) m4_include([m4/ax_prog_perl_modules.m4]) m4_include([m4/ax_with_prog.m4]) m4_include([m4/lrint.m4]) m4_include([m4/lrintf.m4]) enblend-enfuse-4.2/README0000644000175000017500000004664012676176342012102 00000000000000Copyright (C) 2004-2009 Andrew Mihal. Copyright (C) 2009-2016 Christoph Spiel. This file is part of Enblend. * Programs This packages contains the programs Enblend and Enfuse. The source code and further information about Enblend are available at: http://enblend.sf.net ** Enblend Enblend is a tool for compositing images using a Burt&Adelson multiresolution spline. This technique tries to make the seams between the input images invisible. The basic idea is that image features should be blended across a transition zone proportional in size to the spatial frequency of the features. For example, objects like trees and windowpanes have rapid changes in color. By blending these features in a narrow zone, you will not be able to see the seam because the eye already expects to see color changes at the edge of these features. Clouds and sky are the opposite. These features have to be blended across a wide transition zone because any sudden change in color will be immediately noticeable. Enblend expects each input file to have an alpha channel. The alpha channel should indicate the region of the file that has valid image data. Enblend compares the alpha regions in the input files to find the areas where images overlap. Alpha channels can be used to indicate to Enblend that certain portions of an input image should not contribute to the final image. Enblend does not align images for you. Use a tool like Hugin or PanoTools to do this. The files produced by these programs are exactly what Enblend is designed to work with. ** Enfuse Enfuse is a tool for automatic exposure blending, contrast blending and much more. It can be used to fuse an exposure bracketed step automatically into a nicely looking image. * Installation GNU Make is required to build the project, because some of the Makefiles contain pattern rules. ** Tarball ./configure YOUR-OPTIONS-IF-ANY-GO-HERE make make install ** Mercurial Repository *** AutoConf/AutoMake In the root directory of the project issue: make --makefile=Makefile.scm ./configure YOUR-OPTIONS-IF-ANY-GO-HERE make make install The package fully supports VPATH builds. Thus the following command sequence builds in a separate directory. cd ROOT-DIRECTORY make --makefile=Makefile.scm mkdir BUILD-DIR cd BUILD-DIR ROOT-DIRECTORY/configure YOUR-OPTIONS-IF-ANY-GO-HERE make make install If a less verbose output of the Make-process is desired, pass `--enable-silent-rules' to configure(1), or `V=0' to make(1). As out build uses recursion make(1) reports "Entering directory" and "Leaving directory" which can only be suppressed with passing option `--no-print-directory' to make(1). *** CMake The canonical way to build Enblend and Enfuse is with Autotools, this is, autoconf(1) and automake(1). An alternative CMake build has been added since version 4.0. The CMake build strives to replicate the Autotools build. It may or may not work for you. It is currently maintained but not supported, meaning that it could break anywhere anytime in the future. cmake . make make install Analogously to Autotools, CMake allows for VPATH builds: mkdir BUILD-DIR cd BUILD-DIR cmake ROOT-DIRECTORY make make install * Specific Configuration Options Among the usual configuration options of the GNU autoconf system, the configure(1) script offers the following options to tailor Enblend and Enfuse. Remember that configure(1) creates a file called "config.h" that can serve for fine-tuning the configuration. We write the default values of all configuration options in capital letters. ** --enable-on-demand-dynlink=CHECK/yes/no Link Enblend and Enfuse binaries with flags that instruct the dynamic linker to delay loading dynamic libraries until they are actually needed. This feature slightly decreases the load-time of the binaries. ** --enable-openmp=yes/NO -DENABLE_OPENMP=ON/off (CMake) Parallelize parts of Enblend and Enfuse with OpenMP. See http://www.openmp.org/ If auto-detection of OpenMP misfires, set appropriate OPENMP_CXXFLAGS during configuration. For example, CLang++ may need the argument-form of option `-fopenmp': -fopenmp=libiomp5 In addition OpenMP support libraries may live in non-standard places. These too can be specified in OPENMP_CXXFLAGS, because the flags will be used for compilation and linking. When OpenMP support has been enabled, the utilization of special features of the actual, underlying OpenMP implementation can be controlled as usual with the environment variables OMP_NUM_THREADS, OMP_NESTED and OMP_DYNAMIC. See the OpenMP specification for details on the usage of these variables. ** --enable-debug=yes/NO Compile without optimizations and enable all debug-checking code. The default is "no", build an optimized version without debugging symbols. ** --with-dl=CHECK/yes/no/dl/gmodule Enable user-defined exposure weight functions in Enblend. With argument "check", test for POSIX-compatible dynamic-loader (dl) and if unsuccessful for GLib implementation (gmodule). ** --with-tcmalloc=CHECK/yes/no -DENABLE_TCMALLOC=OFF/on (CMake) Compile with Google's TCMalloc. This library generally improves memory allocation performance. Enblend and Enfuse prefer TCMalloc's functions inside OpenMP parallel regions and thereby reduce the load of the operating system's memory allocator. Find more information on TCMalloc at http://goog-perftools.sourceforge.net/doc/tcmalloc.html ** --with-dmalloc=yes/NO Compile with the debug-malloc library. The library is available at http://www.dmalloc.com/. ** --with-openexr=CHECK/yes/no Build with support for reading and writing OpenEXR images. See http://www.openexr.com/ for the required libraries. * CMake Specifics ** Configuration Options These options only apply to CMake. *** -DCPACK_BINARY_:BOOL=OFF/on Create a package for the specified , where is "DEB", "RPM", or "NSIS". *** -DCPACK_BINARY_:BOOL=ON/off Create other packages for the specified , where is "TBZ2", "TGZ", "STGZ", or "TZ". *** -DPACK_SOURCE_:BOOL=OFF/on Create a source package for the specified , where is "TBZ2", "TGZ", "TZ", or "ZIP". ** Configuration Example Creating a RedHat package on OpenSuSE cmake . \ -DDOC=ON \ -DENABLE_OPENMP=ON \ -DCPACK_BINARY_RPM:BOOL=ON make package This will create a package enblend-4.0.595-Linux.rpm, which you may install with sudo rpm -U enblend-4.0.595-Linux.rpm ** Important Configured Make(1) Targets help List all available targets. edit_cache If cmake-gui(1) is installed, start the GUI to edit the "CMakeCache.txt" file. enblend Create an Enblend executable. enfuse Create an Enfuse executable. man Create the manual pages for Enblend and Enfuse. install Install everything in the proper places. package Create package(s) specified with the CPACK_BINARY_:BOOL parameter of CMake. It is preferred to create a package and use the package manager to install it rather than using the "install" target. rebuild_cache In a changed environment (e.g. newly installed packages) this is the way to discard cached values, so that CMake again starts searching for everything. package_source Build a source package like autotools "make dist". * Extra Make(1) Variables ** Compilation You can override Makefile variables the usual way. In addition the build process supplies several variables, all starting with "EXTRA", that add their value to the "usual suspects". These are CPPFLAGS -- EXTRACPPFLAGS CFLAGS -- EXTRACFLAGS CXXFLAGS -- EXTRACXXFLAGS LDFLAGS -- EXTRALDFLAGS All these "EXTRA" are intentionally unaffected by the Automake/Autoconf generation of the Makefiles proper. That way developers can override configured settings in any make(1) run or quickly build the project with new combinations of flags. For example, to quickly add an additional define, use make EXTRACPPFLAGS=-DDEBUG_8BIT_ONLY To compile for coverage analysis, say make EXTRACXXFLAGS="-O0 --coverage" EXTRALDFLAGS="--coverage" analogously for profiling analysis make EXTRACXXFLAGS=-pg EXTRALDFLAGS=-pg ** Documentation Generation We have introduced the variable DYNAMIC_TEX_PREAMBLE to give the maintainers and packagers better control over the generation of the documentation. The contents of the variable goes _before_ `\documentclass' so that even the document class can be selected dynamically. DYNAMIC_TEX_PREAMBLE can define the argument-less macros `\documentclassoptions' which defines LaTeX \documentclass options (thingies within square brackets) and `\finishdynamicpreamble' which is expanded right before `\begin{document}' and thus _after_ all packages have been loaded. Some possibilities for `DYNAMIC_TEX_PREAMBLE' are \hyperreftrue \referencemanualtrue \usepackage[showframe]{geometry} \def\documentclassoptions{11pt,twoside} \def\finishdynamicpreamble{\overfullrule=2pt\relax} * Documentation The distribution includes the manual pages in src/enblend.1 src/enfuse.1 After the configuration you can build documentation in PostScript, HTML, and possibly PDF formats. make ps make pdf make html The default paper size for all non-HTML formats is DIN A4. Override make(1) variable `PAPERSIZE' to get e.g. Letter format. The default resolution is 600 dpi; override it with `PRINT_RESOLUTION'. The _printed_ versions can be formatted in two different styles: the usual LaTeX `report' and `refman' style that borrows from old reference manuals. Pass DYNAMIC_TEX_PREAMBLE=\referencemanualtrue to make(1) when generating a non-HTML format to get the `refman' style. The reference manual style does _not_ work with HTML, in other words, hevea(1) will barf. By default only PDFLaTeX turns on HyperRef, for all other translators (in particular if PDF is indirectly generated) it must be enabled with DYNAMIC_TEX_PREAMBLE=\hyperreftrue ** HTML Generation The default target `html' builds the HTML documentation as monolithic files, which means the single HTML file "enblend.html" for Enblend and "enfuse.html" for Enfuse. To build split versions with one chapter per file of each of them use the target `split-html', where the root files will be `enblend-index.html' and `enfuse-index.html' . Install the broken-down version with `install-split-html'. ** PDF Generation The canonical way to reach at PDF files i.e. make pdf is directly, via PDFLaTeX: LaTeX -> PDF. If for some reason this path does not work, we provide two alternatives. *** Alternative 1: LaTeX -> DVI -> PDF Use dvipdfmx(1) to convert the final DVI files to PDF. It is recommended to issue a make clean before starting to construct the PDF files this way! Add the following commands to DYNAMIC_TEX_PREAMBLE: - To get correctly positioned graphics \PassOptionsToPackage{dvipdfmx}{graphicx} - For all the hyperref goodies (e.g. clickable cross refferences) \PassOptionsToPackage{dvipdfmx}{hyperref}\hyperreftrue - To get the right color associations \PassOptionsToPackage{dvipdfmx}{color} Sometimes EXTRA_LATEX_FLAGS='-shell-escape' may be required. The targets are called "enblend.dvi.pdf" and "enfuse.dvi.pdf", rename the products if necessary. See doc/Makefile.am for details. *** Alternative 2: LaTeX -> DVI -> PostScript -> PDF Use GhostScript (gs(1)) in the incarnation of ps2pdf(1) to convert the final PostScript files to PDF. None of the hyperref goodies makes it through dvips(1). The targets are called "enblend.ps.pdf" and "enfuse.ps.pdf"; rename if necessary; see doc/Makefile.am for details. ** Required Tools For Building the Documentation Note that some additional packages are required to build these formats: convert - ImageMagick's swiss army knife of graphics format conversion found at http://www.imagemagick.org/. dvips - Convert TeX's DVI format to PostScript. gnuplot - Render plots (.gp) in text, PNG, EPS, and PDF formats. Check out http://www.gnuplot.info/. hevea - Convert LaTeX to HTML. Find more information at http://hevea.inria.fr/. latex, pdflatex - Typeset the LaTeX documents in DVI or PDF. makeindex - Index generation for several typesetters. dot - Graph generation. Part of the `GraphViz' suite. See http://www.graphviz.org/. rsvg-convert - Convert SVG to a variety of other formats, not only raster images, but also EPS. Check out http://librsvg.sourceforge.net/. The tool texloganalyser(1) is optional. Its sole use is to beautify LaTeX output in non-verbose (V=0) mode. * Operating System Specific Instructions and Hints ** GNU/Linux *** High-Performance Binaries To configure and compile high-performance versions of Enblend and Enfuse configure SMP boxes with --enable-openmp and pass EXTRACXXFLAGS="-march=native -O2" to make(1). The resulting binaries are pretty fast, although other configuration options or compiler flags might improve their performance even more. *** Xmi and Xi To avoid direct linkage to the two X11 libraries Xmi and Xi add "--without-x" to the parameters of configure(1). ** MacOSX *** Compiling on MacOSX On MacOSX you can build Enblend/Enfuse with Fink and with MacPorts. This README only describes the MacPorts way. **** Prerequisites - XCode: Install the XCode version for your MacOSX version. Download it from http://developer.apple.com/tools/download/ - MacPorts: Install MacPorts for your MacOSX version. Download it from http://www.macports.org/ **** Provide necessary dependencies From the command line: $ sudo port install make lcms boost jpeg tiff libpng OpenEXR mercurial Note that Enblend/Enfuse can be build via AutoConf/AutoMake and via CMake. The latter is experimental. If you want to build via CMake, add "cmake" to the previous command line after "mercurial" like this: $ sudo port install make lcms boost jpeg tiff libpng OpenEXR mercurial cmake **** Compile As MacPorts resides in /opt/local, which is not a standard library/binary/include path for most source packages, you need to specify that during the configure step. Via AutoConf/AutoMake: cd enblend make --makefile=Makefile.scm mkdir build cd build CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib ../configure make sudo make install Via CMake: cd enblend make --makefile=Makefile.scm mkdir build cd build CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib cmake .. make sudo make install This will install Enblend/Enfuse in /usr/local. **** Other compilation options Please also check the AutoConf/AutoMake and CMake variables for more build options. ** Win *** General There are two different archives: one with 32-bit executables, the other one with 64-bit executables. Both variants are compiled with multi-threaded support (via OpenMP). *** Compiling on Windows **** Prerequisites You will need to following tools for compiling: - MS Visual C++ 2015, works also with Community Edition (older compiler may work, but have not been tested) - CMake, at least version 2.8 - Perl, e.g. ActiveState Perl CMake expects all sources and libraries in one folder. So, create a folder, e.g., "d:\src", extract Enblend/Enfuse into this folder, and also put all libraries into this folder. You need the following libraries for reading and writing different image formats. We state the version and the folder name of the libraries used as of March 2016 in square brackets. - libtiff [libtiff-4.0.6 in tiff] - zlib, required by libtiff [1.2.8 in zlib] - libjpeg (optional) [jpeg-9b] - libpng (optional) [libpng-1.6.21 in libpng] - OpenEXR and IlmBase (optional), compiled libraries are expected in folder "Deploy" [OpenEXR-2.2.0 and IlmBase-2.2.0] - vigra, required, should be compiled against same libtifff, libjpeg, libpng and OpenEXR as used for Enblend/Enfuse [1.10.0 in vigra] Enblend/Enfuse also depend on the following libraries: - Boost [1.60 in boost_1_60_0] - Only header files are used by default. - Optionally, Enblend/Enfuse can use the Filesystem Library. However, this library needs to compiled against STLport. - Little-CMS2 [2.4 in lcm2-2.4] **** Compile 1. Start cmake-gui or cmake-setup. 2. Enter path to Enblend/Enfuse source in "Where is the source code". 3. Enter path where to build the executable, e.g. "d:\src\build-enblend". In following, it will be denoted as . 4. Select "Configure" when asked for a generator select the appropriate generator. 5. Activate the appropriate options. ***** ENABLE_OPENMP=on/OFF Parallelize parts of Enblend and Enfuse with OpenMP. See http://www.openmp.org/ If OpenMP support has been enabled, the utilization of special features of the actual, underlying OpenMP implementation can be controlled as usual with the environment variables OMP_NUM_THREADS, OMP_NESTED and OMP_DYNAMIC. See the OpenMP specification for details on the usage of these variables. ***** ENABLE_SSE2=on/OFF Creates executable which make use of the advanced features (SSE2) of modern processors. ***** DOC=on/OFF Building the documentation works also on Windows. It requires more tools (see above). Some tools have several different variants for Windows available, but not all work with Enblend/Enfuse documentation. If you experience errors try another variant or version. **** Compile (cont.) 6. Select "Configure". Maybe you need start the configuration step several times until all dependencies are resolved. 7. Select "Generate". 8. Close CMake. 9. Open solution file \enblend.sln. 10. Select "Release" in Solution Configuration pull-down menu, and then choose Build > Build Solution. This step takes some time. 11. Select project "INSTALL" in Solution Explorer, and then choose Build > Project Only > Build Only INSTALL. 12. Close Visual C++ 2008 Express Edition 13. Find the generated executables in \INSTALLDIR\FILES. * License Enblend 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. Enblend 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 Enblend; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Local Variables: mode: outline End: enblend-enfuse-4.2/configure0000755000175000017500000134524512676242416013131 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for enblend-enfuse 4.2. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: https://bugs.launchpad.net/enblend about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='enblend-enfuse' PACKAGE_TARNAME='enblend-enfuse' PACKAGE_VERSION='4.2' PACKAGE_STRING='enblend-enfuse 4.2' PACKAGE_BUGREPORT='https://bugs.launchpad.net/enblend' PACKAGE_URL='4.2' ac_unique_file="src/enblend.cc" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS DYNAMIC_TEX_PREAMBLE BUILD_DOC_FALSE BUILD_DOC_TRUE DVIPDF PS2PDF SVGCONVERT DOT M4 GNUPLOT SPLITHTML LATEX2HTML_LIBDIR LATEX2HTML CONVERT DVIPS MAKEINDEX TEXLOGANALYSER xstring url suffix shorttoc ragged2e microtype listings latexsym index ifpdf hyphenat hyperref graphicx footnote float enumitem color bold_extra amsmath boretti_classesansparametre refrep report latex PDFLATEX LATEX HELP2MAN PERL POW_LIB LIBOBJS HAVE_INLINE EXTRA_LIBS BOOST_LDFLAGS BOOST_CPPFLAGS host_os host_vendor host_cpu host build_os build_vendor build_cpu build DYNAMIC_EXPOSURE_WEIGHTS_FALSE DYNAMIC_EXPOSURE_WEIGHTS_TRUE DL_IMPLEMENTATION VIGRAIMPEX_LIB OPENEXR_LIBS OPENEXR_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG CXXCPP SED RANLIB EGREP GREP ac_ct_AR AR am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE ac_ct_CC CFLAGS CC HAVE_CXX11 am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking enable_on_demand_dynlink with_tcmalloc with_openexr with_dmalloc with_dl with_boost with_boost_libdir with_hevea enable_debug enable_image_cache enable_openmp ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC CC CFLAGS CXXCPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR OPENEXR_CFLAGS OPENEXR_LIBS VIGRAIMPEX_LIB LATEX2HTML LATEX2HTML_LIBDIR DYNAMIC_TEX_PREAMBLE' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures enblend-enfuse 4.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/enblend-enfuse] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of enblend-enfuse 4.2:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-on-demand-dynlink use on-demand dynamic linking [default=check] --enable-debug turn on debugging [default=no] --enable-image-cache allow for processing of large images [default=no] --enable-openmp compile with OpenMP [default=no] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-tcmalloc use Google's TCMalloc library [default=check] --with-openexr use OpenEXR [default=check] --with-dmalloc use dmalloc, as in http://www.dmalloc.com/dmalloc.tar.gz --with-dl add support for dynamic loading [default=check] --with-boost[=ARG] use Boost library from a standard location (ARG=yes), from the specified location (ARG=), or disable it (ARG=no) [ARG=yes] --with-boost-libdir=LIB_DIR Force given directory for boost libraries. Note that this will override library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located. --with-hevea=[PATH] absolute path to hevea executable Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CC C compiler command CFLAGS C compiler flags CXXCPP C++ preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path OPENEXR_CFLAGS C compiler flags for OPENEXR, overriding pkg-config OPENEXR_LIBS linker flags for OPENEXR, overriding pkg-config VIGRAIMPEX_LIB name of Vigra import/export-library LATEX2HTML Absolute path to hevea executable LATEX2HTML_LIBDIR Directory where LaTeX to HTML translator's additional files reside DYNAMIC_TEX_PREAMBLE LaTeX commands to add to top of preamble Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . enblend-enfuse home page: <4.2>. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF enblend-enfuse configure 4.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_cxx_try_run LINENO # ------------------------ # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_cxx_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_cxx_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_compile # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ------------------------------------------------- ## ## Report this to https://bugs.launchpad.net/enblend ## ## ------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel # ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES # --------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_cxx_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_type # ac_fn_cxx_check_decl LINENO SYMBOL VAR INCLUDES # ----------------------------------------------- # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. ac_fn_cxx_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_decl # ac_fn_cxx_check_func LINENO FUNC VAR # ------------------------------------ # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_cxx_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by enblend-enfuse $as_me 4.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in . "$srcdir"/.; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in . \"$srcdir\"/." "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. ac_config_headers="$ac_config_headers config.h" am__api_version='1.14' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='enblend-enfuse' VERSION='4.2' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C++ compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi ax_cxx_compile_cxx11_required=truednl ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_success=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 $as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; } if ${ax_cv_cxx_compile_cxx11+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; typedef check> right_angle_brackets; int a; decltype(a) b; typedef check check_type; check_type c; check_type&& cr = static_cast(c); auto d = a; _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ax_cv_cxx_compile_cxx11=yes else ax_cv_cxx_compile_cxx11=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 $as_echo "$ax_cv_cxx_compile_cxx11" >&6; } if test x$ax_cv_cxx_compile_cxx11 = xyes; then ac_success=yes fi if test x$ac_success = xno; then for switch in -std=gnu++11 -std=gnu++0x; do cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 $as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } if eval \${$cachevar+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $switch" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; typedef check> right_angle_brackets; int a; decltype(a) b; typedef check check_type; check_type c; check_type&& cr = static_cast(c); auto d = a; _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval $cachevar=yes else eval $cachevar=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CXXFLAGS="$ac_save_CXXFLAGS" fi eval ac_res=\$$cachevar { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test x\$$cachevar = xyes; then CXXFLAGS="$CXXFLAGS $switch" ac_success=yes break fi done fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test x$ax_cxx_compile_cxx11_required = xtrue; then if test x$ac_success = xno; then as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 fi else if test x$ac_success = xno; then HAVE_CXX11=0 { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 $as_echo "$as_me: No compiler with C++11 support was found" >&6;} else HAVE_CXX11=1 $as_echo "#define HAVE_CXX11 1" >>confdefs.h fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports as_const()" >&5 $as_echo_n "checking whether the compiler supports as_const()... " >&6; } if ${ax_cv_cxx_as_const+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { std::string s("foo"); const std::string& const_s = std::as_const(s) ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ax_cv_cxx_as_const=yes else ax_cv_cxx_as_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_as_const" >&5 $as_echo "$ax_cv_cxx_as_const" >&6; } if test "X$ax_cv_cxx_as_const" = Xyes; then : $as_echo "#define HAVE_AS_CONST /**/" >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="${ac_tool_prefix}ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_AR"; then ac_ct_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_AR" = x; then AR=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi else AR="$ac_cv_prog_AR" fi if test -n "$ac_tool_prefix"; then for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} { $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 $as_echo_n "checking the archiver ($AR) interface... " >&6; } if ${am_cv_ar_interface+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am_cv_ar_interface=ar cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int some_variable = 0; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 $as_echo "$am_cv_ar_interface" >&6; } case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) as_fn_error $? "could not determine $AR interface" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac enable_on_demand_dynamic_linking=check { $as_echo "$as_me:${as_lineno-$LINENO}: checking if on-demand dynamic linking is desired" >&5 $as_echo_n "checking if on-demand dynamic linking is desired... " >&6; } # Check whether --enable-on-demand-dynlink was given. if test "${enable_on_demand_dynlink+set}" = set; then : enableval=$enable_on_demand_dynlink; { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5 $as_echo "$enableval" >&6; }; enable_on_demand_dynamic_linking=$enableval else { $as_echo "$as_me:${as_lineno-$LINENO}: result: check" >&5 $as_echo "check" >&6; }; enable_on_demand_dynamic_linking=check fi have_on_demand_dynamic_linking=no if test "$enable_on_demand_dynamic_linking" = no; then : have_on_demand_dynamic_linking=no else if test -n "$enable_on_demand_dynamic_linking" || \ test "$enable_on_demand_dynamic_linking" = yes || \ test "$enable_on_demand_dynamic_linking" = check; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for on-demand dynamic linking" >&5 $as_echo_n "checking for on-demand dynamic linking... " >&6; } save_ldflags="$LDFLAGS" LDFLAGS="-Wl,--as-needed -Wl,--no-copy-dt-needed-entries ${LDFLAGS}" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { strlen("foo") ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; have_on_demand_dynamic_linking=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_ldflags" fi fi if test "$have_on_demand_dynamic_linking" = yes; then LDFLAGS="-Wl,--as-needed -Wl,--no-copy-dt-needed-entries ${LDFLAGS}" fi # Checks for libraries. # We check for TCMalloc so early to make it the last user library on # the linker command line. It will then gobble all undefined # references to malloc(3) and free(3) and thus relieve the O/S even # more. use_tcmalloc=no # Check whether --with-tcmalloc was given. if test "${with_tcmalloc+set}" = set; then : withval=$with_tcmalloc; else with_tcmalloc=check fi if test "$with_tcmalloc" = check -o "$with_tcmalloc" = yes; then : for ac_header in gperftools/tcmalloc.h tcmalloc.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF break fi done if test "$ac_cv_header_tcmalloc_h" = yes -o "$with_tcmalloc" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tc_malloc" >&5 $as_echo_n "checking for library containing tc_malloc... " >&6; } if ${ac_cv_search_tc_malloc+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tc_malloc (); int main () { return tc_malloc (); ; return 0; } _ACEOF for ac_lib in '' tcmalloc, tcmalloc_minimal; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_search_tc_malloc=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_tc_malloc+:} false; then : break fi done if ${ac_cv_search_tc_malloc+:} false; then : else ac_cv_search_tc_malloc=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_tc_malloc" >&5 $as_echo "$ac_cv_search_tc_malloc" >&6; } ac_res=$ac_cv_search_tc_malloc if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" use_tcmalloc=yes $as_echo "#define HAVE_TCMALLOC 1" >>confdefs.h fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5 $as_echo_n "checking for sqrt in -lm... " >&6; } if ${ac_cv_lib_m_sqrt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sqrt (); int main () { return sqrt (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_m_sqrt=yes else ac_cv_lib_m_sqrt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5 $as_echo "$ac_cv_lib_m_sqrt" >&6; } if test "x$ac_cv_lib_m_sqrt" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cblas_dgemm in -lgslcblas" >&5 $as_echo_n "checking for cblas_dgemm in -lgslcblas... " >&6; } if ${ac_cv_lib_gslcblas_cblas_dgemm+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgslcblas $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char cblas_dgemm (); int main () { return cblas_dgemm (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_gslcblas_cblas_dgemm=yes else ac_cv_lib_gslcblas_cblas_dgemm=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gslcblas_cblas_dgemm" >&5 $as_echo "$ac_cv_lib_gslcblas_cblas_dgemm" >&6; } if test "x$ac_cv_lib_gslcblas_cblas_dgemm" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGSLCBLAS 1 _ACEOF LIBS="-lgslcblas $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gsl_blas_dgemm in -lgsl" >&5 $as_echo_n "checking for gsl_blas_dgemm in -lgsl... " >&6; } if ${ac_cv_lib_gsl_gsl_blas_dgemm+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gsl_blas_dgemm (); int main () { return gsl_blas_dgemm (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_gsl_gsl_blas_dgemm=yes else ac_cv_lib_gsl_gsl_blas_dgemm=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gsl_gsl_blas_dgemm" >&5 $as_echo "$ac_cv_lib_gsl_gsl_blas_dgemm" >&6; } if test "x$ac_cv_lib_gsl_gsl_blas_dgemm" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGSL 1 _ACEOF LIBS="-lgsl $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzopen in -lz" >&5 $as_echo_n "checking for gzopen in -lz... " >&6; } if ${ac_cv_lib_z_gzopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gzopen (); int main () { return gzopen (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_z_gzopen=yes else ac_cv_lib_z_gzopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzopen" >&5 $as_echo "$ac_cv_lib_z_gzopen" >&6; } if test "x$ac_cv_lib_z_gzopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBZ 1 _ACEOF LIBS="-lz $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: Compiling without libz." >&5 $as_echo "$as_me: Compiling without libz." >&6;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jpeg_finish_compress in -ljpeg" >&5 $as_echo_n "checking for jpeg_finish_compress in -ljpeg... " >&6; } if ${ac_cv_lib_jpeg_jpeg_finish_compress+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ljpeg $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char jpeg_finish_compress (); int main () { return jpeg_finish_compress (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_jpeg_jpeg_finish_compress=yes else ac_cv_lib_jpeg_jpeg_finish_compress=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_jpeg_finish_compress" >&5 $as_echo "$ac_cv_lib_jpeg_jpeg_finish_compress" >&6; } if test "x$ac_cv_lib_jpeg_jpeg_finish_compress" = xyes; then : LIBS="-ljpeg ${LIBS}"; $as_echo "#define HasJPEG 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: Compiling without support for jpeg files." >&5 $as_echo "$as_me: Compiling without support for jpeg files." >&6;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_init_io in -lpng" >&5 $as_echo_n "checking for png_init_io in -lpng... " >&6; } if ${ac_cv_lib_png_png_init_io+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpng $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char png_init_io (); int main () { return png_init_io (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_png_png_init_io=yes else ac_cv_lib_png_png_init_io=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png_png_init_io" >&5 $as_echo "$ac_cv_lib_png_png_init_io" >&6; } if test "x$ac_cv_lib_png_png_init_io" = xyes; then : LIBS="-lpng ${LIBS}"; $as_echo "#define HasPNG 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: Compiling without support for png files." >&5 $as_echo "$as_me: Compiling without support for png files." >&6;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFOpen in -ltiff" >&5 $as_echo_n "checking for TIFFOpen in -ltiff... " >&6; } if ${ac_cv_lib_tiff_TIFFOpen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltiff $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char TIFFOpen (); int main () { return TIFFOpen (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_tiff_TIFFOpen=yes else ac_cv_lib_tiff_TIFFOpen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tiff_TIFFOpen" >&5 $as_echo "$ac_cv_lib_tiff_TIFFOpen" >&6; } if test "x$ac_cv_lib_tiff_TIFFOpen" = xyes; then : LIBS="-ltiff ${LIBS}"; $as_echo "#define HasTIFF 1" >>confdefs.h else as_fn_error $? "libtiff is required to compile Enblend." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cmsCreateTransform in -llcms2" >&5 $as_echo_n "checking for cmsCreateTransform in -llcms2... " >&6; } if ${ac_cv_lib_lcms2_cmsCreateTransform+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-llcms2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char cmsCreateTransform (); int main () { return cmsCreateTransform (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_lcms2_cmsCreateTransform=yes else ac_cv_lib_lcms2_cmsCreateTransform=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lcms2_cmsCreateTransform" >&5 $as_echo "$ac_cv_lib_lcms2_cmsCreateTransform" >&6; } if test "x$ac_cv_lib_lcms2_cmsCreateTransform" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBLCMS2 1 _ACEOF LIBS="-llcms2 $LIBS" else as_fn_error $? "liblcms2 is required to compile Enblend." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if OpenEXR is wanted" >&5 $as_echo_n "checking if OpenEXR is wanted... " >&6; } # Check whether --with-openexr was given. if test "${with_openexr+set}" = set; then : withval=$with_openexr; else with_openexr=check fi if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi if test "$with_openexr" = no; then : { $as_echo "$as_me:${as_lineno-$LINENO}: disabling OpenEXR" >&5 $as_echo "$as_me: disabling OpenEXR" >&6;} have_exr=no else if test "$with_openexr" = yes || test "$with_openexr" = check; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENEXR" >&5 $as_echo_n "checking for OPENEXR... " >&6; } if test -n "$OPENEXR_CFLAGS"; then pkg_cv_OPENEXR_CFLAGS="$OPENEXR_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"OpenEXR >= 1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "OpenEXR >= 1.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_OPENEXR_CFLAGS=`$PKG_CONFIG --cflags "OpenEXR >= 1.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$OPENEXR_LIBS"; then pkg_cv_OPENEXR_LIBS="$OPENEXR_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"OpenEXR >= 1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "OpenEXR >= 1.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_OPENEXR_LIBS=`$PKG_CONFIG --libs "OpenEXR >= 1.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then OPENEXR_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "OpenEXR >= 1.0" 2>&1` else OPENEXR_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "OpenEXR >= 1.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$OPENEXR_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"OpenEXR support disabled: \" $OPENEXR_PKG_ERRORS" >&5 $as_echo "$as_me: WARNING: \"OpenEXR support disabled: \" $OPENEXR_PKG_ERRORS" >&2;} have_exr=no elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"OpenEXR support disabled: \" $OPENEXR_PKG_ERRORS" >&5 $as_echo "$as_me: WARNING: \"OpenEXR support disabled: \" $OPENEXR_PKG_ERRORS" >&2;} have_exr=no else OPENEXR_CFLAGS=$pkg_cv_OPENEXR_CFLAGS OPENEXR_LIBS=$pkg_cv_OPENEXR_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HasEXR 1" >>confdefs.h have_exr=yes fi LIBS="${OPENEXR_LIBS} $LIBS" CFLAGS="${OPENEXR_CFLAGS} $CFLAGS" CXXFLAGS="${OPENEXR_CFLAGS} $CXXFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_exr=no fi fi if test -z "$VIGRAIMPEX_LIB"; then VIGRAIMPEX_LIB='-lvigraimpex' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Vigra import/export-library" >&5 $as_echo_n "checking for Vigra import/export-library... " >&6; } LIBS="$VIGRAIMPEX_LIB $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { vigra::impexListFormats() ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "libvigraimpex is required to compile Enblend." "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { vigra::BRGBImage image; vigra::BImage alpha; vigra::ImageImportInfo info("image.tif"); info.setImageIndex(99); vigra::importImageAlpha(info, destImage(image), destImage(alpha)); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Vigra was found, but it was not recent enough." "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # Memory allocation debug support { $as_echo "$as_me:${as_lineno-$LINENO}: checking if malloc debugging is wanted" >&5 $as_echo_n "checking if malloc debugging is wanted... " >&6; } # Check whether --with-dmalloc was given. if test "${with_dmalloc+set}" = set; then : withval=$with_dmalloc; if test "$withval" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define WITH_DMALLOC 1" >>confdefs.h if test $acx_pthread_ok = yes; then LIBS="$LIBS -ldmallocthcxx" enable_dmalloc="yes (thread aware)" else LIBS="$LIBS -ldmalloccxx" enable_dmalloc=yes fi LDFLAGS="$LDFLAGS -g" $as_echo "#define DMALLOC 1" >>confdefs.h $as_echo "#define DMALLOC_FUNC_CHECK 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } enable_dmalloc=no fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } enable_dmalloc=no fi DL_IMPLEMENTATION='' dynload_implementation='' enable_dynload=no # Check whether --with-dl was given. if test "${with_dl+set}" = set; then : withval=$with_dl; else with_dl=check fi if test "$with_dl" != no; then : if test "$with_dl" = check -o "$with_dl" = yes -o "$with_dl" = dl; then for ac_header in dlfcn.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done if test "$ac_cv_header_dlfcn_h" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 $as_echo_n "checking for library containing dlopen... " >&6; } if ${ac_cv_search_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF for ac_lib in '' dl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_search_dlopen=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_dlopen+:} false; then : break fi done if ${ac_cv_search_dlopen+:} false; then : else ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 $as_echo "$ac_cv_search_dlopen" >&6; } ac_res=$ac_cv_search_dlopen if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" $as_echo "#define HAVE_DL 1" >>confdefs.h $as_echo "#define POSIX_DL 1" >>confdefs.h DL_IMPLEMENTATION='libdynamic_loader_a-posix_implementation.o' dynload_implementation='(via dl)' enable_dynload=yes fi fi fi if test "$enable_dynload" != yes -a \( "$with_dl" = check -o "$with_dl" = gmodule \); then for ac_header in gmodule.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "gmodule.h" "ac_cv_header_gmodule_h" "$ac_includes_default" if test "x$ac_cv_header_gmodule_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GMODULE_H 1 _ACEOF fi done if test "$ac_cv_header_gmodule_h" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing g_module_open" >&5 $as_echo_n "checking for library containing g_module_open... " >&6; } if ${ac_cv_search_g_module_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char g_module_open (); int main () { return g_module_open (); ; return 0; } _ACEOF for ac_lib in '' gmodule-2.0; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_search_g_module_open=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_g_module_open+:} false; then : break fi done if ${ac_cv_search_g_module_open+:} false; then : else ac_cv_search_g_module_open=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_g_module_open" >&5 $as_echo "$ac_cv_search_g_module_open" >&6; } ac_res=$ac_cv_search_g_module_open if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" $as_echo "#define HAVE_DL 1" >>confdefs.h $as_echo "#define GMODULE_DL 1" >>confdefs.h DL_IMPLEMENTATION='libdynamic_loader_a-gmodule_implementation.o' dynload_implementation='(via gmodule-2.0)' enable_dynload=yes fi fi fi fi if test "$enable_dynload" = yes; then DYNAMIC_EXPOSURE_WEIGHTS_TRUE= DYNAMIC_EXPOSURE_WEIGHTS_FALSE='#' else DYNAMIC_EXPOSURE_WEIGHTS_TRUE='#' DYNAMIC_EXPOSURE_WEIGHTS_FALSE= fi # Checks for header files. ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } if eval \${$as_ac_Header+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval "$as_ac_Header=yes" else eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$as_ac_Header { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' dir; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' x; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi for ac_header in fenv.h limits.h stdlib.h string.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_cxx_check_header_mongrel "$LINENO" "sys/times.h" "ac_cv_header_sys_times_h" "$ac_includes_default" if test "x$ac_cv_header_sys_times_h" = xyes; then : $as_echo "#define HAVE_SYS_TIMES_H 1" >>confdefs.h fi ac_fn_cxx_check_header_mongrel "$LINENO" "tiffio.h" "ac_cv_header_tiffio_h" "$ac_includes_default" if test "x$ac_cv_header_tiffio_h" = xyes; then : else as_fn_error $? "libtiff-devel header files are required to compile Enblend." "$LINENO" 5 fi ac_fn_cxx_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default" if test "x$ac_cv_header_jpeglib_h" = xyes; then : else as_fn_error $? "libjpeg-devel header files are required to compile Enblend." "$LINENO" 5 fi ac_fn_cxx_check_header_mongrel "$LINENO" "png.h" "ac_cv_header_png_h" "$ac_includes_default" if test "x$ac_cv_header_png_h" = xyes; then : else as_fn_error $? "libpng-devel header files are required to compile Enblend." "$LINENO" 5 fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_fn_cxx_check_header_mongrel "$LINENO" "vigra/basicimage.hxx" "ac_cv_header_vigra_basicimage_hxx" "$ac_includes_default" if test "x$ac_cv_header_vigra_basicimage_hxx" = xyes; then : else as_fn_error $? "Vigra \"basicimage.hxx\" header file is required to compile Enblend." "$LINENO" 5 fi # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Check whether --with-boost was given. if test "${with_boost+set}" = set; then : withval=$with_boost; if test "$withval" = "no"; then want_boost="no" elif test "$withval" = "yes"; then want_boost="yes" ac_boost_path="" else want_boost="yes" ac_boost_path="$withval" fi else want_boost="yes" fi # Check whether --with-boost-libdir was given. if test "${with_boost_libdir+set}" = set; then : withval=$with_boost_libdir; if test -d "$withval" then ac_boost_lib_path="$withval" else as_fn_error $? "--with-boost-libdir expected directory name" "$LINENO" 5 fi else ac_boost_lib_path="" fi if test "x$want_boost" = "xyes"; then boost_lib_version_req=1.55 boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([0-9]*\.[0-9]*\)'` boost_lib_version_req_major=`expr $boost_lib_version_req : '\([0-9]*\)'` boost_lib_version_req_minor=`expr $boost_lib_version_req : '[0-9]*\.\([0-9]*\)'` boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[0-9]*\.[0-9]*\.\([0-9]*\)'` if test "x$boost_lib_version_req_sub_minor" = "x" ; then boost_lib_version_req_sub_minor="0" fi WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for boostlib >= $boost_lib_version_req" >&5 $as_echo_n "checking for boostlib >= $boost_lib_version_req... " >&6; } succeeded=no libsubdirs="lib" ax_arch=`uname -m` case $ax_arch in x86_64|ppc64|s390x|sparc64|aarch64) libsubdirs="lib64 lib lib64" ;; esac libsubdirs="lib/${host_cpu}-${host_os} $libsubdirs" case ${host_cpu} in i?86) libsubdirs="lib/i386-${host_os} $libsubdirs" ;; esac if test "$ac_boost_path" != ""; then BOOST_CPPFLAGS="-I$ac_boost_path/include" for ac_boost_path_tmp in $libsubdirs; do if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp" break fi done elif test "$cross_compiling" != yes; then for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then for libsubdir in $libsubdirs ; do if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir" BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" break; fi done fi if test "$ac_boost_lib_path" != ""; then BOOST_LDFLAGS="-L$ac_boost_lib_path" fi CPPFLAGS_SAVED="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" export CPPFLAGS LDFLAGS_SAVED="$LDFLAGS" LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" export LDFLAGS ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if BOOST_VERSION >= $WANT_BOOST_VERSION // Everything is okay #else # error Boost version is too old #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } succeeded=yes found_system=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test "x$succeeded" != "xyes"; then _version=0 if test "$ac_boost_path" != ""; then if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` V_CHECK=`expr $_version_tmp \> $_version` if test "$V_CHECK" = "1" ; then _version=$_version_tmp fi VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" done fi else if test "$cross_compiling" != yes; then for ac_boost_path in /usr /usr/local /opt /opt/local ; do if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` V_CHECK=`expr $_version_tmp \> $_version` if test "$V_CHECK" = "1" ; then _version=$_version_tmp best_path=$ac_boost_path fi done fi done VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" if test "$ac_boost_lib_path" = ""; then for libsubdir in $libsubdirs ; do if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done BOOST_LDFLAGS="-L$best_path/$libsubdir" fi fi if test "x$BOOST_ROOT" != "x"; then for libsubdir in $libsubdirs ; do if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'` stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` stage_version_shorten=`expr $stage_version : '\([0-9]*\.[0-9]*\)'` V_CHECK=`expr $stage_version_shorten \>\= $_version` if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: We will use a staged boost library from $BOOST_ROOT" >&5 $as_echo "$as_me: We will use a staged boost library from $BOOST_ROOT" >&6;} BOOST_CPPFLAGS="-I$BOOST_ROOT" BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir" fi fi fi fi CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" export CPPFLAGS LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" export LDFLAGS ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if BOOST_VERSION >= $WANT_BOOST_VERSION // Everything is okay #else # error Boost version is too old #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } succeeded=yes found_system=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi if test "$succeeded" != "yes" ; then if test "$_version" = "0" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation." >&5 $as_echo "$as_me: We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation." >&6;} else { $as_echo "$as_me:${as_lineno-$LINENO}: Your boost libraries seems to old (version $_version)." >&5 $as_echo "$as_me: Your boost libraries seems to old (version $_version)." >&6;} fi # execute ACTION-IF-NOT-FOUND (if present): as_fn_error $? "Boost version 1.55 or later is required to compile Enblend." "$LINENO" 5 else $as_echo "#define HAVE_BOOST /**/" >>confdefs.h # execute ACTION-IF-FOUND (if present): : fi CPPFLAGS="$CPPFLAGS_SAVED" LDFLAGS="$LDFLAGS_SAVED" fi ac_fn_cxx_check_header_mongrel "$LINENO" "boost/optional.hpp" "ac_cv_header_boost_optional_hpp" "$ac_includes_default" if test "x$ac_cv_header_boost_optional_hpp" = xyes; then : else as_fn_error $? "Boost \"optional\" header file is required to compile Enblend." "$LINENO" 5 fi ac_fn_cxx_check_header_mongrel "$LINENO" "gsl/gsl_errno.h" "ac_cv_header_gsl_gsl_errno_h" "$ac_includes_default" if test "x$ac_cv_header_gsl_gsl_errno_h" = xyes; then : else as_fn_error $? "GNU Scientific Library (GSL) header file \"gsl_errno\" is required to compile Enblend." "$LINENO" 5 fi ac_fn_cxx_check_header_mongrel "$LINENO" "gsl/gsl_min.h" "ac_cv_header_gsl_gsl_min_h" "$ac_includes_default" if test "x$ac_cv_header_gsl_gsl_min_h" = xyes; then : else as_fn_error $? "GNU Scientific Library (GSL) header file \"gsl_min\" is required to compile Enblend." "$LINENO" 5 fi ac_fn_cxx_check_header_mongrel "$LINENO" "gsl/gsl_multimin.h" "ac_cv_header_gsl_gsl_multimin_h" "$ac_includes_default" if test "x$ac_cv_header_gsl_gsl_multimin_h" = xyes; then : else as_fn_error $? "GNU Scientific Library (GSL) header file \"gsl_multimin\" is required to compile Enblend." "$LINENO" 5 fi ac_fn_cxx_check_header_mongrel "$LINENO" "gsl/gsl_rng.h" "ac_cv_header_gsl_gsl_rng_h" "$ac_includes_default" if test "x$ac_cv_header_gsl_gsl_rng_h" = xyes; then : else as_fn_error $? "GNU Scientific Library (GSL) header file \"gsl_rng\" is required to compile Enblend." "$LINENO" 5 fi ac_fn_cxx_check_header_mongrel "$LINENO" "gsl/gsl_vector.h" "ac_cv_header_gsl_gsl_vector_h" "$ac_includes_default" if test "x$ac_cv_header_gsl_gsl_vector_h" = xyes; then : else as_fn_error $? "GNU Scientific Library (GSL) header file \"gsl_vector\" is required to compile Enblend." "$LINENO" 5 fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_fn_cxx_check_header_mongrel "$LINENO" "lcms2.h" "ac_cv_header_lcms2_h" "$ac_includes_default" if test "x$ac_cv_header_lcms2_h" = xyes; then : else as_fn_error $? "lcms2 header files are required to compile Enblend." "$LINENO" 5 fi # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; /* See body of main program for 'e'. */ char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { bool e = &s; *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_cxx_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac if test "$ac_cv_c_inline" != no; then $as_echo "#define HAVE_INLINE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5 $as_echo_n "checking for C/C++ restrict keyword... " >&6; } if ${ac_cv_c_restrict+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_restrict=no # The order here caters to the fact that C++ does not require restrict. for ac_kw in __restrict __restrict__ _Restrict restrict; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ typedef int * int_ptr; int foo (int_ptr $ac_kw ip) { return ip[0]; } int main () { int s[1]; int * $ac_kw t = s; t[0] = 0; return foo(t) ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_restrict=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_restrict" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5 $as_echo "$ac_cv_c_restrict" >&6; } case $ac_cv_c_restrict in restrict) ;; no) $as_echo "#define restrict /**/" >>confdefs.h ;; *) cat >>confdefs.h <<_ACEOF #define restrict $ac_cv_c_restrict _ACEOF ;; esac $as_echo "#define RESTRICT restrict" >>confdefs.h ac_fn_cxx_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" if test "x$ac_cv_type_off_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define off_t long int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sig_atomic_t" >&5 $as_echo_n "checking for sig_atomic_t... " >&6; } if ${ac_cv_type_sig_atomic_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { sig_atomic_t foo = 1; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_type_sig_atomic_t=yes else ac_cv_type_sig_atomic_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "$ac_cv_type_sig_atomic_t" = no; then $as_echo "#define sig_atomic_t int" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_sig_atomic_t" >&5 $as_echo "$ac_cv_type_sig_atomic_t" >&6; } ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi ac_fn_cxx_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" if test "x$ac_cv_type_ptrdiff_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PTRDIFF_T 1 _ACEOF fi # Checks for library functions. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether closedir returns void" >&5 $as_echo_n "checking whether closedir returns void... " >&6; } if ${ac_cv_func_closedir_void+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_closedir_void=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #include <$ac_header_dirent> #ifndef __cplusplus int closedir (); #endif int main () { return closedir (opendir (".")) != 0; ; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : ac_cv_func_closedir_void=no else ac_cv_func_closedir_void=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_closedir_void" >&5 $as_echo "$ac_cv_func_closedir_void" >&6; } if test $ac_cv_func_closedir_void = yes; then $as_echo "#define CLOSEDIR_VOID 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5 $as_echo_n "checking for error_at_line... " >&6; } if ${ac_cv_lib_error_at_line+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { error_at_line (0, 0, "", 0, "an error occurred"); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_error_at_line=yes else ac_cv_lib_error_at_line=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_error_at_line" >&5 $as_echo "$ac_cv_lib_error_at_line" >&6; } if test $ac_cv_lib_error_at_line = no; then case " $LIBOBJS " in *" error.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS error.$ac_objext" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 $as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } if ${ac_cv_sys_largefile_source+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* for off_t */ #include int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_sys_largefile_source=no; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGEFILE_SOURCE 1 #include /* for off_t */ #include int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_sys_largefile_source=1; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_cv_sys_largefile_source=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 $as_echo "$ac_cv_sys_largefile_source" >&6; } case $ac_cv_sys_largefile_source in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source _ACEOF ;; esac rm -rf conftest* # We used to try defining _XOPEN_SOURCE=500 too, to work around a bug # in glibc 2.1.3, but that breaks too many other things. # If you want fseeko and ftello with glibc, upgrade to a fixed glibc. if test $ac_cv_sys_largefile_source != unknown; then $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h fi if ${ac_cv_func_setvbuf_reversed+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_func_setvbuf_reversed=no fi ac_fn_cxx_check_decl "$LINENO" "strerror_r" "ac_cv_have_decl_strerror_r" "$ac_includes_default" if test "x$ac_cv_have_decl_strerror_r" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRERROR_R $ac_have_decl _ACEOF for ac_func in strerror_r do : ac_fn_cxx_check_func "$LINENO" "strerror_r" "ac_cv_func_strerror_r" if test "x$ac_cv_func_strerror_r" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRERROR_R 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strerror_r returns char *" >&5 $as_echo_n "checking whether strerror_r returns char *... " >&6; } if ${ac_cv_func_strerror_r_char_p+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_func_strerror_r_char_p=no if test $ac_cv_have_decl_strerror_r = yes; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { char buf[100]; char x = *strerror_r (0, buf, sizeof buf); char *p = strerror_r (0, buf, sizeof buf); return !p || x; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_func_strerror_r_char_p=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else # strerror_r is not declared. Choose between # systems that have relatively inaccessible declarations for the # function. BeOS and DEC UNIX 4.0 fall in this category, but the # former has a strerror_r that returns char*, while the latter # has a strerror_r that returns `int'. # This test should segfault on the DEC system. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default extern char *strerror_r (); int main () { char buf[100]; char x = *strerror_r (0, buf, sizeof buf); return ! isalpha (x); ; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : ac_cv_func_strerror_r_char_p=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strerror_r_char_p" >&5 $as_echo "$ac_cv_func_strerror_r_char_p" >&6; } if test $ac_cv_func_strerror_r_char_p = yes; then $as_echo "#define STRERROR_R_CHAR_P 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strtod" >&5 $as_echo_n "checking for working strtod... " >&6; } if ${ac_cv_func_strtod+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_strtod=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #ifndef strtod double strtod (); #endif int main() { { /* Some versions of Linux strtod mis-parse strings with leading '+'. */ char *string = " +69"; char *term; double value; value = strtod (string, &term); if (value != 69 || term != (string + 4)) return 1; } { /* Under Solaris 2.4, strtod returns the wrong value for the terminating character under some conditions. */ char *string = "NaN"; char *term; strtod (string, &term); if (term != string && *(term - 1) == 0) return 1; } return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : ac_cv_func_strtod=yes else ac_cv_func_strtod=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strtod" >&5 $as_echo "$ac_cv_func_strtod" >&6; } if test $ac_cv_func_strtod = no; then case " $LIBOBJS " in *" strtod.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strtod.$ac_objext" ;; esac ac_fn_cxx_check_func "$LINENO" "pow" "ac_cv_func_pow" if test "x$ac_cv_func_pow" = xyes; then : fi if test $ac_cv_func_pow = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5 $as_echo_n "checking for pow in -lm... " >&6; } if ${ac_cv_lib_m_pow+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pow (); int main () { return pow (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_m_pow=yes else ac_cv_lib_m_pow=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5 $as_echo "$ac_cv_lib_m_pow" >&6; } if test "x$ac_cv_lib_m_pow" = xyes; then : POW_LIB=-lm else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find library containing definition of pow" >&5 $as_echo "$as_me: WARNING: cannot find library containing definition of pow" >&2;} fi fi fi for ac_func in atexit clock_gettime \ fesetround floor \ memset mkstemp select \ pow sqrt \ sqrt strchr strcspn strdup strerror strpbrk strrchr strtok_r strtol strtoul do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # lrint and lrintf { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lrint" >&5 $as_echo_n "checking for lrint... " >&6; } if ${ac_cv_c99_lrint+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _ISOC9X_SOURCE 1 #define _ISOC99_SOURCE 1 #define __USE_ISOC99 1 #define __USE_ISOC9X 1 #include int main () { int value = lrint (0.432) ; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c99_lrint=yes else ac_cv_c99_lrint=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c99_lrint" >&5 $as_echo "$ac_cv_c99_lrint" >&6; } if test $ac_cv_c99_lrint = yes; then $as_echo "#define HAVE_LRINT 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lrintf" >&5 $as_echo_n "checking for lrintf... " >&6; } if ${ac_cv_c99_lrintf+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _ISOC9X_SOURCE 1 #define _ISOC99_SOURCE 1 #define __USE_ISOC99 1 #define __USE_ISOC9X 1 #include int main () { int value = lrintf (0.432) ; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c99_lrintf=yes else ac_cv_c99_lrintf=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c99_lrintf" >&5 $as_echo "$ac_cv_c99_lrintf" >&6; } if test $ac_cv_c99_lrintf = yes; then $as_echo "#define HAVE_LRINTF 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BOOST_FALLTHROUGH" >&5 $as_echo_n "checking for BOOST_FALLTHROUGH... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { BOOST_FALLTHROUGH ; return 0; } _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : ac_found=yes; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else ac_found=no; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f conftest.err conftest.i conftest.$ac_ext if test "$ac_found" = no; then $as_echo "#define BOOST_FALLTHROUGH ((void) 0)" >>confdefs.h fi # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PERL+:} false; then : $as_echo_n "(cached) " >&6 else case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="false" ;; esac fi PERL=$ac_cv_path_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$PERL" = false; then as_fn_error $? "cannot find perl" "$LINENO" 5 fi # Make sure we have perl if test -z "$PERL"; then # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PERL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PERL"; then ac_cv_prog_PERL="$PERL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PERL="perl" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PERL=$ac_cv_prog_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$PERL" != x; then ax_perl_modules_failed=0 for ax_perl_module in 'Sys::Hostname' ; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl module $ax_perl_module" >&5 $as_echo_n "checking for perl module $ax_perl_module... " >&6; } # Would be nice to log result here, but can't rely on autoconf internals $PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1 if test $? -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; ax_perl_modules_failed=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; }; fi done # Run optional shell commands if test "$ax_perl_modules_failed" = 0; then : else : as_fn_error $? "missing Perl module Sys::Hostname" "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find perl" >&5 $as_echo "$as_me: WARNING: could not find perl" >&2;} fi # Make sure we have perl if test -z "$PERL"; then # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PERL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PERL"; then ac_cv_prog_PERL="$PERL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PERL="perl" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PERL=$ac_cv_prog_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$PERL" != x; then ax_perl_modules_failed=0 for ax_perl_module in 'Time::Zone' ; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl module $ax_perl_module" >&5 $as_echo_n "checking for perl module $ax_perl_module... " >&6; } # Would be nice to log result here, but can't rely on autoconf internals $PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1 if test $? -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; ax_perl_modules_failed=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; }; fi done # Run optional shell commands if test "$ax_perl_modules_failed" = 0; then : else : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing Perl module Time::Zone" >&5 $as_echo "$as_me: WARNING: missing Perl module Time::Zone" >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find perl" >&5 $as_echo "$as_me: WARNING: could not find perl" >&2;} fi # Documentation if test "$cross_compiling" = no; then HELP2MAN=${HELP2MAN-"${am_missing_run}help2man"} else HELP2MAN=: fi can_build_doc=yes for ac_prog in latex elatex lambda do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_LATEX+:} false; then : $as_echo_n "(cached) " >&6 else case $LATEX in [\\/]* | ?:[\\/]*) ac_cv_path_LATEX="$LATEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_LATEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi LATEX=$ac_cv_path_LATEX if test -n "$LATEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LATEX" >&5 $as_echo "$LATEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LATEX" && break done test -n "$LATEX" || LATEX="{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX translator" >&5 $as_echo "$as_me: WARNING: missing LaTeX translator" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc latex"" # Extract the first word of "pdflatex", so it can be a program name with args. set dummy pdflatex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PDFLATEX+:} false; then : $as_echo_n "(cached) " >&6 else case $PDFLATEX in [\\/]* | ?:[\\/]*) ac_cv_path_PDFLATEX="$PDFLATEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PDFLATEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PDFLATEX" && ac_cv_path_PDFLATEX="{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing PDFLaTeX translator -- no direct translation of LaTeX to PDF available" >&5 $as_echo "$as_me: WARNING: missing PDFLaTeX translator -- no direct translation of LaTeX to PDF available" >&2;} missing_for_doc="$missing_for_doc pdflatex"" ;; esac fi PDFLATEX=$ac_cv_path_PDFLATEX if test -n "$PDFLATEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PDFLATEX" >&5 $as_echo "$PDFLATEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$latex" != 'no' then for ac_prog in latex elatex lambda do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_latex+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$latex"; then ac_cv_prog_latex="$latex" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_latex="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi latex=$ac_cv_prog_latex if test -n "$latex"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $latex" >&5 $as_echo "$latex" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$latex" && break done test -n "$latex" || latex="no" export latex; if test $latex = "no" ; then as_fn_error $? "Unable to find a LaTeX application" "$LINENO" 5; fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } report=$ac_cv_latex_class_report ; export report; if test "$report" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing document class report.cls" >&5 $as_echo "$as_me: WARNING: missing document class report.cls" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc report.cls" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class refrep" >&5 $as_echo_n "checking for class refrep... " >&6; } if ${ac_cv_latex_class_refrep+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{refrep}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_refrep=yes; export ac_cv_latex_class_refrep; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_refrep" >&5 $as_echo "$ac_cv_latex_class_refrep" >&6; } refrep=$ac_cv_latex_class_refrep ; export refrep; if test "$refrep" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing document class refrep.cls -- no Reference Manual Style available" >&5 $as_echo "$as_me: WARNING: missing document class refrep.cls -- no Reference Manual Style available" >&2;} missing_for_doc="$missing_for_doc refrep.cls" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for amsmath in class report" >&5 $as_echo_n "checking for amsmath in class report... " >&6; } if ${ac_cv_latex_amsmath_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_amsmath_report="no"; export ac_cv_latex_amsmath_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{amsmath} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_amsmath_report=yes; export ac_cv_latex_amsmath_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_amsmath_report" >&5 $as_echo "$ac_cv_latex_amsmath_report" >&6; } amsmath=$ac_cv_latex_amsmath_report; export amsmath; if test "$amsmath" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package amsmath" >&5 $as_echo "$as_me: WARNING: missing LaTeX package amsmath" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc amsmath.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bold-extra in class report" >&5 $as_echo_n "checking for bold-extra in class report... " >&6; } if ${ac_cv_latex_bold_extra_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_bold_extra_report="no"; export ac_cv_latex_bold_extra_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{bold-extra} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_bold_extra_report=yes; export ac_cv_latex_bold_extra_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_bold_extra_report" >&5 $as_echo "$ac_cv_latex_bold_extra_report" >&6; } bold_extra=$ac_cv_latex_bold_extra_report; export bold_extra; if test "$bold_extra" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package bold-extra" >&5 $as_echo "$as_me: WARNING: missing LaTeX package bold-extra" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc bold-extra.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for color in class report" >&5 $as_echo_n "checking for color in class report... " >&6; } if ${ac_cv_latex_color_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_color_report="no"; export ac_cv_latex_color_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{color} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_color_report=yes; export ac_cv_latex_color_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_color_report" >&5 $as_echo "$ac_cv_latex_color_report" >&6; } color=$ac_cv_latex_color_report; export color; if test "$color" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package color" >&5 $as_echo "$as_me: WARNING: missing LaTeX package color" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc color.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for enumitem in class report" >&5 $as_echo_n "checking for enumitem in class report... " >&6; } if ${ac_cv_latex_enumitem_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_enumitem_report="no"; export ac_cv_latex_enumitem_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{enumitem} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_enumitem_report=yes; export ac_cv_latex_enumitem_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_enumitem_report" >&5 $as_echo "$ac_cv_latex_enumitem_report" >&6; } enumitem=$ac_cv_latex_enumitem_report; export enumitem; if test "$enumitem" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package enumitem" >&5 $as_echo "$as_me: WARNING: missing LaTeX package enumitem" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc enumitem.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for float in class report" >&5 $as_echo_n "checking for float in class report... " >&6; } if ${ac_cv_latex_float_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_float_report="no"; export ac_cv_latex_float_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{float} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_float_report=yes; export ac_cv_latex_float_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_float_report" >&5 $as_echo "$ac_cv_latex_float_report" >&6; } float=$ac_cv_latex_float_report; export float; if test "$float" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package float" >&5 $as_echo "$as_me: WARNING: missing LaTeX package float" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc float.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for footnote in class report" >&5 $as_echo_n "checking for footnote in class report... " >&6; } if ${ac_cv_latex_footnote_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_footnote_report="no"; export ac_cv_latex_footnote_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{footnote} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_footnote_report=yes; export ac_cv_latex_footnote_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_footnote_report" >&5 $as_echo "$ac_cv_latex_footnote_report" >&6; } footnote=$ac_cv_latex_footnote_report; export footnote; if test "$footnote" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package footnote" >&5 $as_echo "$as_me: WARNING: missing LaTeX package footnote" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc footnote.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for graphicx in class report" >&5 $as_echo_n "checking for graphicx in class report... " >&6; } if ${ac_cv_latex_graphicx_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_graphicx_report="no"; export ac_cv_latex_graphicx_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{graphicx} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_graphicx_report=yes; export ac_cv_latex_graphicx_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_graphicx_report" >&5 $as_echo "$ac_cv_latex_graphicx_report" >&6; } graphicx=$ac_cv_latex_graphicx_report; export graphicx; if test "$graphicx" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package graphicx" >&5 $as_echo "$as_me: WARNING: missing LaTeX package graphicx" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc graphicx.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hyperref in class report" >&5 $as_echo_n "checking for hyperref in class report... " >&6; } if ${ac_cv_latex_hyperref_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_hyperref_report="no"; export ac_cv_latex_hyperref_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{hyperref} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_hyperref_report=yes; export ac_cv_latex_hyperref_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_hyperref_report" >&5 $as_echo "$ac_cv_latex_hyperref_report" >&6; } hyperref=$ac_cv_latex_hyperref_report; export hyperref; if test "$hyperref" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package hyperref" >&5 $as_echo "$as_me: WARNING: missing LaTeX package hyperref" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc hyperref.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hyphenat in class report" >&5 $as_echo_n "checking for hyphenat in class report... " >&6; } if ${ac_cv_latex_hyphenat_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_hyphenat_report="no"; export ac_cv_latex_hyphenat_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{hyphenat} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_hyphenat_report=yes; export ac_cv_latex_hyphenat_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_hyphenat_report" >&5 $as_echo "$ac_cv_latex_hyphenat_report" >&6; } hyphenat=$ac_cv_latex_hyphenat_report; export hyphenat; if test "$hyphenat" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package hyphenat" >&5 $as_echo "$as_me: WARNING: missing LaTeX package hyphenat" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc hyphenat.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ifpdf in class report" >&5 $as_echo_n "checking for ifpdf in class report... " >&6; } if ${ac_cv_latex_ifpdf_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_ifpdf_report="no"; export ac_cv_latex_ifpdf_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{ifpdf} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_ifpdf_report=yes; export ac_cv_latex_ifpdf_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_ifpdf_report" >&5 $as_echo "$ac_cv_latex_ifpdf_report" >&6; } ifpdf=$ac_cv_latex_ifpdf_report; export ifpdf; if test "$ifpdf" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package ifpdf" >&5 $as_echo "$as_me: WARNING: missing LaTeX package ifpdf" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc ifpdf.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for index in class report" >&5 $as_echo_n "checking for index in class report... " >&6; } if ${ac_cv_latex_index_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_index_report="no"; export ac_cv_latex_index_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{index} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_index_report=yes; export ac_cv_latex_index_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_index_report" >&5 $as_echo "$ac_cv_latex_index_report" >&6; } index=$ac_cv_latex_index_report; export index; if test "$index" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package index" >&5 $as_echo "$as_me: WARNING: missing LaTeX package index" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc index.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for latexsym in class report" >&5 $as_echo_n "checking for latexsym in class report... " >&6; } if ${ac_cv_latex_latexsym_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_latexsym_report="no"; export ac_cv_latex_latexsym_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{latexsym} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_latexsym_report=yes; export ac_cv_latex_latexsym_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_latexsym_report" >&5 $as_echo "$ac_cv_latex_latexsym_report" >&6; } latexsym=$ac_cv_latex_latexsym_report; export latexsym; if test "$latexsym" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package latexsym" >&5 $as_echo "$as_me: WARNING: missing LaTeX package latexsym" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc latexsym.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for listings in class report" >&5 $as_echo_n "checking for listings in class report... " >&6; } if ${ac_cv_latex_listings_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_listings_report="no"; export ac_cv_latex_listings_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{listings} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_listings_report=yes; export ac_cv_latex_listings_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_listings_report" >&5 $as_echo "$ac_cv_latex_listings_report" >&6; } listings=$ac_cv_latex_listings_report; export listings; if test "$listings" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package listings" >&5 $as_echo "$as_me: WARNING: missing LaTeX package listings" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc listings.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for microtype in class report" >&5 $as_echo_n "checking for microtype in class report... " >&6; } if ${ac_cv_latex_microtype_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_microtype_report="no"; export ac_cv_latex_microtype_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{microtype} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_microtype_report=yes; export ac_cv_latex_microtype_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_microtype_report" >&5 $as_echo "$ac_cv_latex_microtype_report" >&6; } microtype=$ac_cv_latex_microtype_report; export microtype; if test "$microtype" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package microtype" >&5 $as_echo "$as_me: WARNING: missing LaTeX package microtype" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc microtype.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ragged2e in class report" >&5 $as_echo_n "checking for ragged2e in class report... " >&6; } if ${ac_cv_latex_ragged2e_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_ragged2e_report="no"; export ac_cv_latex_ragged2e_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{ragged2e} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_ragged2e_report=yes; export ac_cv_latex_ragged2e_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_ragged2e_report" >&5 $as_echo "$ac_cv_latex_ragged2e_report" >&6; } ragged2e=$ac_cv_latex_ragged2e_report; export ragged2e; if test "$ragged2e" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package ragged2e" >&5 $as_echo "$as_me: WARNING: missing LaTeX package ragged2e" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc ragged2e.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shorttoc in class report" >&5 $as_echo_n "checking for shorttoc in class report... " >&6; } if ${ac_cv_latex_shorttoc_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_shorttoc_report="no"; export ac_cv_latex_shorttoc_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{shorttoc} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_shorttoc_report=yes; export ac_cv_latex_shorttoc_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_shorttoc_report" >&5 $as_echo "$ac_cv_latex_shorttoc_report" >&6; } shorttoc=$ac_cv_latex_shorttoc_report; export shorttoc; if test "$shorttoc" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package shorttoc" >&5 $as_echo "$as_me: WARNING: missing LaTeX package shorttoc" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc shorttoc.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix in class report" >&5 $as_echo_n "checking for suffix in class report... " >&6; } if ${ac_cv_latex_suffix_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_suffix_report="no"; export ac_cv_latex_suffix_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{suffix} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_suffix_report=yes; export ac_cv_latex_suffix_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_suffix_report" >&5 $as_echo "$ac_cv_latex_suffix_report" >&6; } suffix=$ac_cv_latex_suffix_report; export suffix; if test "$suffix" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package suffix" >&5 $as_echo "$as_me: WARNING: missing LaTeX package suffix" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc suffix.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for url in class report" >&5 $as_echo_n "checking for url in class report... " >&6; } if ${ac_cv_latex_url_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_url_report="no"; export ac_cv_latex_url_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{url} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_url_report=yes; export ac_cv_latex_url_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_url_report" >&5 $as_echo "$ac_cv_latex_url_report" >&6; } url=$ac_cv_latex_url_report; export url; if test "$url" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package url" >&5 $as_echo "$as_me: WARNING: missing LaTeX package url" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc url.sty" fi if test "$ac_cv_latex_class_report" = "" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for class report" >&5 $as_echo_n "checking for class report... " >&6; } if ${ac_cv_latex_class_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex echo "\\documentclass{report}" > testconf.tex cat >> testconf.tex << \EOF \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_class_report=yes; export ac_cv_latex_class_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_class_report" >&5 $as_echo "$ac_cv_latex_class_report" >&6; } boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparametre; export boretti_classesansparametre; else boretti_classesansparametre=$ac_cv_latex_class_report ; export boretti_classesansparemetre; fi; if test $boretti_classesansparametre = "no" ; then as_fn_error $? "Unable to find report class" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xstring in class report" >&5 $as_echo_n "checking for xstring in class report... " >&6; } if ${ac_cv_latex_xstring_report+:} false; then : $as_echo_n "(cached) " >&6 else rm -rf .tmps_latex mkdir .tmps_latex cd .tmps_latex ac_cv_latex_xstring_report="no"; export ac_cv_latex_xstring_report; cat > testconf.tex << \EOF \documentclass{report} \usepackage{xstring} \begin{document} \end{document} EOF cat testconf.tex | $latex 2>&1 1>/dev/null && ac_cv_latex_xstring_report=yes; export ac_cv_latex_xstring_report; cd .. rm -rf .tmps_latex fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_latex_xstring_report" >&5 $as_echo "$ac_cv_latex_xstring_report" >&6; } xstring=$ac_cv_latex_xstring_report; export xstring; if test "$xstring" = "no" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing LaTeX package xstring" >&5 $as_echo "$as_me: WARNING: missing LaTeX package xstring" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc xstring.sty" fi fi if test "$PERL" != false; then # Make sure we have perl if test -z "$PERL"; then # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PERL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PERL"; then ac_cv_prog_PERL="$PERL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PERL="perl" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PERL=$ac_cv_prog_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$PERL" != x; then ax_perl_modules_failed=0 for ax_perl_module in 'File::Basename' ; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl module $ax_perl_module" >&5 $as_echo_n "checking for perl module $ax_perl_module... " >&6; } # Would be nice to log result here, but can't rely on autoconf internals $PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1 if test $? -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; ax_perl_modules_failed=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; }; fi done # Run optional shell commands if test "$ax_perl_modules_failed" = 0; then : else : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing Perl module File::Basename" >&5 $as_echo "$as_me: WARNING: missing Perl module File::Basename" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc File::Basename" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find perl" >&5 $as_echo "$as_me: WARNING: could not find perl" >&2;} fi # Make sure we have perl if test -z "$PERL"; then # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PERL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PERL"; then ac_cv_prog_PERL="$PERL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PERL="perl" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PERL=$ac_cv_prog_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$PERL" != x; then ax_perl_modules_failed=0 for ax_perl_module in 'FindBin' ; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl module $ax_perl_module" >&5 $as_echo_n "checking for perl module $ax_perl_module... " >&6; } # Would be nice to log result here, but can't rely on autoconf internals $PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1 if test $? -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; ax_perl_modules_failed=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; }; fi done # Run optional shell commands if test "$ax_perl_modules_failed" = 0; then : else : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing Perl module FindBin" >&5 $as_echo "$as_me: WARNING: missing Perl module FindBin" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc FindBin" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find perl" >&5 $as_echo "$as_me: WARNING: could not find perl" >&2;} fi # Make sure we have perl if test -z "$PERL"; then # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PERL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PERL"; then ac_cv_prog_PERL="$PERL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PERL="perl" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PERL=$ac_cv_prog_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$PERL" != x; then ax_perl_modules_failed=0 for ax_perl_module in 'Getopt::Long' ; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl module $ax_perl_module" >&5 $as_echo_n "checking for perl module $ax_perl_module... " >&6; } # Would be nice to log result here, but can't rely on autoconf internals $PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1 if test $? -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; ax_perl_modules_failed=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; }; fi done # Run optional shell commands if test "$ax_perl_modules_failed" = 0; then : else : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing Perl module Getopt::Long" >&5 $as_echo "$as_me: WARNING: missing Perl module Getopt::Long" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc Getopt::Long" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find perl" >&5 $as_echo "$as_me: WARNING: could not find perl" >&2;} fi # Make sure we have perl if test -z "$PERL"; then # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PERL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PERL"; then ac_cv_prog_PERL="$PERL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PERL="perl" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PERL=$ac_cv_prog_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$PERL" != x; then ax_perl_modules_failed=0 for ax_perl_module in 'IO::File' ; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl module $ax_perl_module" >&5 $as_echo_n "checking for perl module $ax_perl_module... " >&6; } # Would be nice to log result here, but can't rely on autoconf internals $PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1 if test $? -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; ax_perl_modules_failed=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; }; fi done # Run optional shell commands if test "$ax_perl_modules_failed" = 0; then : else : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing Perl module IO::File" >&5 $as_echo "$as_me: WARNING: missing Perl module IO::File" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc IO::File" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find perl" >&5 $as_echo "$as_me: WARNING: could not find perl" >&2;} fi # Make sure we have perl if test -z "$PERL"; then # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PERL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PERL"; then ac_cv_prog_PERL="$PERL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PERL="perl" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PERL=$ac_cv_prog_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$PERL" != x; then ax_perl_modules_failed=0 for ax_perl_module in 'IO::Handle' ; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl module $ax_perl_module" >&5 $as_echo_n "checking for perl module $ax_perl_module... " >&6; } # Would be nice to log result here, but can't rely on autoconf internals $PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1 if test $? -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; ax_perl_modules_failed=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; }; fi done # Run optional shell commands if test "$ax_perl_modules_failed" = 0; then : else : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing Perl module IO::Handle" >&5 $as_echo "$as_me: WARNING: missing Perl module IO::Handle" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc IO::Handle" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find perl" >&5 $as_echo "$as_me: WARNING: could not find perl" >&2;} fi # Make sure we have perl if test -z "$PERL"; then # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PERL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PERL"; then ac_cv_prog_PERL="$PERL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PERL="perl" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PERL=$ac_cv_prog_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$PERL" != x; then ax_perl_modules_failed=0 for ax_perl_module in 'Readonly' ; do { $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl module $ax_perl_module" >&5 $as_echo_n "checking for perl module $ax_perl_module... " >&6; } # Would be nice to log result here, but can't rely on autoconf internals $PERL -e "use $ax_perl_module; exit" > /dev/null 2>&1 if test $? -ne 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; ax_perl_modules_failed=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; }; fi done # Run optional shell commands if test "$ax_perl_modules_failed" = 0; then : else : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing Perl module Readonly" >&5 $as_echo "$as_me: WARNING: missing Perl module Readonly" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc Readonly" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find perl" >&5 $as_echo "$as_me: WARNING: could not find perl" >&2;} fi fi # Extract the first word of "texloganalyser", so it can be a program name with args. set dummy texloganalyser; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_TEXLOGANALYSER+:} false; then : $as_echo_n "(cached) " >&6 else case $TEXLOGANALYSER in [\\/]* | ?:[\\/]*) ac_cv_path_TEXLOGANALYSER="$TEXLOGANALYSER" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_TEXLOGANALYSER="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_TEXLOGANALYSER" && ac_cv_path_TEXLOGANALYSER="cat" ;; esac fi TEXLOGANALYSER=$ac_cv_path_TEXLOGANALYSER if test -n "$TEXLOGANALYSER"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEXLOGANALYSER" >&5 $as_echo "$TEXLOGANALYSER" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$TEXLOGANALYSER" = cat; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find texloganalyser; will substitute cat(1)" >&5 $as_echo "$as_me: WARNING: cannot find texloganalyser; will substitute cat(1)" >&2;} missing_for_doc="$missing_for_doc texloganalyser" fi # Extract the first word of "makeindex", so it can be a program name with args. set dummy makeindex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MAKEINDEX+:} false; then : $as_echo_n "(cached) " >&6 else case $MAKEINDEX in [\\/]* | ?:[\\/]*) ac_cv_path_MAKEINDEX="$MAKEINDEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MAKEINDEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MAKEINDEX" && ac_cv_path_MAKEINDEX="false" ;; esac fi MAKEINDEX=$ac_cv_path_MAKEINDEX if test -n "$MAKEINDEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKEINDEX" >&5 $as_echo "$MAKEINDEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$MAKEINDEX" = false; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find makeindex; will not be able to build documentation with index" >&5 $as_echo "$as_me: WARNING: cannot find makeindex; will not be able to build documentation with index" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc makeindex" fi # Extract the first word of "dvips", so it can be a program name with args. set dummy dvips; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DVIPS+:} false; then : $as_echo_n "(cached) " >&6 else case $DVIPS in [\\/]* | ?:[\\/]*) ac_cv_path_DVIPS="$DVIPS" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DVIPS="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_DVIPS" && ac_cv_path_DVIPS="false" ;; esac fi DVIPS=$ac_cv_path_DVIPS if test -n "$DVIPS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DVIPS" >&5 $as_echo "$DVIPS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$DVIPS" = false; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find dvips; will not be able to build PostScript documentation" >&5 $as_echo "$as_me: WARNING: cannot find dvips; will not be able to build PostScript documentation" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc dvips" fi # Extract the first word of "convert", so it can be a program name with args. set dummy convert; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_CONVERT+:} false; then : $as_echo_n "(cached) " >&6 else case $CONVERT in [\\/]* | ?:[\\/]*) ac_cv_path_CONVERT="$CONVERT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_CONVERT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_CONVERT" && ac_cv_path_CONVERT="false" ;; esac fi CONVERT=$ac_cv_path_CONVERT if test -n "$CONVERT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CONVERT" >&5 $as_echo "$CONVERT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$CONVERT" = false; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find convert; will not be able to build documentation" >&5 $as_echo "$as_me: WARNING: cannot find convert; will not be able to build documentation" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc convert" fi if test -z "$LATEX2HTML"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether hevea executable path has been provided" >&5 $as_echo_n "checking whether hevea executable path has been provided... " >&6; } # Check whether --with-hevea was given. if test "${with_hevea+set}" = set; then : withval=$with_hevea; if test "$withval" != yes -a "$withval" != no; then : LATEX2HTML="$withval" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LATEX2HTML" >&5 $as_echo "$LATEX2HTML" >&6; } else LATEX2HTML="" { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if test "$withval" != no; then : # Extract the first word of "hevea", so it can be a program name with args. set dummy hevea; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_LATEX2HTML+:} false; then : $as_echo_n "(cached) " >&6 else case $LATEX2HTML in [\\/]* | ?:[\\/]*) ac_cv_path_LATEX2HTML="$LATEX2HTML" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_LATEX2HTML="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_LATEX2HTML" && ac_cv_path_LATEX2HTML="false" ;; esac fi LATEX2HTML=$ac_cv_path_LATEX2HTML if test -n "$LATEX2HTML"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LATEX2HTML" >&5 $as_echo "$LATEX2HTML" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } # Extract the first word of "hevea", so it can be a program name with args. set dummy hevea; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_LATEX2HTML+:} false; then : $as_echo_n "(cached) " >&6 else case $LATEX2HTML in [\\/]* | ?:[\\/]*) ac_cv_path_LATEX2HTML="$LATEX2HTML" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_LATEX2HTML="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_LATEX2HTML" && ac_cv_path_LATEX2HTML="false" ;; esac fi LATEX2HTML=$ac_cv_path_LATEX2HTML if test -n "$LATEX2HTML"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LATEX2HTML" >&5 $as_echo "$LATEX2HTML" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test "$LATEX2HTML" = false; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find LaTeX to HTML translator; will not be able to build HTML documentation" >&5 $as_echo "$as_me: WARNING: cannot find LaTeX to HTML translator; will not be able to build HTML documentation" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc hevea" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking $LATEX2HTML library directory" >&5 $as_echo_n "checking $LATEX2HTML library directory... " >&6; } LATEX2HTML_LIBDIR=$($LATEX2HTML -version | sed -n 's/^library directory: \(.*\)/\1/p') if test -z "$LATEX2HTML_LIBDIR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } elif test -d "$LATEX2HTML_LIBDIR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LATEX2HTML_LIBDIR" >&5 $as_echo "$LATEX2HTML_LIBDIR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: missing" >&5 $as_echo "missing" >&6; } fi fi # Extract the first word of "hacha", so it can be a program name with args. set dummy hacha; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_SPLITHTML+:} false; then : $as_echo_n "(cached) " >&6 else case $SPLITHTML in [\\/]* | ?:[\\/]*) ac_cv_path_SPLITHTML="$SPLITHTML" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_SPLITHTML="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_SPLITHTML" && ac_cv_path_SPLITHTML="false" ;; esac fi SPLITHTML=$ac_cv_path_SPLITHTML if test -n "$SPLITHTML"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SPLITHTML" >&5 $as_echo "$SPLITHTML" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$SPLITHTML" = false; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find hacha; will not be able to split HTML documentation on request" >&5 $as_echo "$as_me: WARNING: cannot find hacha; will not be able to split HTML documentation on request" >&2;} fi # Extract the first word of "gnuplot", so it can be a program name with args. set dummy gnuplot; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GNUPLOT+:} false; then : $as_echo_n "(cached) " >&6 else case $GNUPLOT in [\\/]* | ?:[\\/]*) ac_cv_path_GNUPLOT="$GNUPLOT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GNUPLOT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GNUPLOT" && ac_cv_path_GNUPLOT="false" ;; esac fi GNUPLOT=$ac_cv_path_GNUPLOT if test -n "$GNUPLOT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GNUPLOT" >&5 $as_echo "$GNUPLOT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GNUPLOT" = false; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find gnuplot; will not be able to build documentation" >&5 $as_echo "$as_me: WARNING: cannot find gnuplot; will not be able to build documentation" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc gnuplot" fi # Extract the first word of "m4", so it can be a program name with args. set dummy m4; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_M4+:} false; then : $as_echo_n "(cached) " >&6 else case $M4 in [\\/]* | ?:[\\/]*) ac_cv_path_M4="$M4" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_M4="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_M4" && ac_cv_path_M4="false" ;; esac fi M4=$ac_cv_path_M4 if test -n "$M4"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $M4" >&5 $as_echo "$M4" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$M4" = false; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find m4; will not be able to build documentation" >&5 $as_echo "$as_me: WARNING: cannot find m4; will not be able to build documentation" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc m4" fi # Extract the first word of "dot", so it can be a program name with args. set dummy dot; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DOT+:} false; then : $as_echo_n "(cached) " >&6 else case $DOT in [\\/]* | ?:[\\/]*) ac_cv_path_DOT="$DOT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DOT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_DOT" && ac_cv_path_DOT="false" ;; esac fi DOT=$ac_cv_path_DOT if test -n "$DOT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOT" >&5 $as_echo "$DOT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$DOT" = false; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find dot; will not be able to build documentation" >&5 $as_echo "$as_me: WARNING: cannot find dot; will not be able to build documentation" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc dot" fi # Extract the first word of "rsvg-convert", so it can be a program name with args. set dummy rsvg-convert; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_SVGCONVERT+:} false; then : $as_echo_n "(cached) " >&6 else case $SVGCONVERT in [\\/]* | ?:[\\/]*) ac_cv_path_SVGCONVERT="$SVGCONVERT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_SVGCONVERT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_SVGCONVERT" && ac_cv_path_SVGCONVERT="false" ;; esac fi SVGCONVERT=$ac_cv_path_SVGCONVERT if test -n "$SVGCONVERT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SVGCONVERT" >&5 $as_echo "$SVGCONVERT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$SVGCONVERT" = false; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find rsvg-convert; will not be able to build documentation" >&5 $as_echo "$as_me: WARNING: cannot find rsvg-convert; will not be able to build documentation" >&2;} can_build_doc=no missing_for_doc="$missing_for_doc rsvg-convert" fi for ac_prog in ps2pdf ps2pdf14 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PS2PDF+:} false; then : $as_echo_n "(cached) " >&6 else case $PS2PDF in [\\/]* | ?:[\\/]*) ac_cv_path_PS2PDF="$PS2PDF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PS2PDF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PS2PDF=$ac_cv_path_PS2PDF if test -n "$PS2PDF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PS2PDF" >&5 $as_echo "$PS2PDF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PS2PDF" && break done test -n "$PS2PDF" || PS2PDF="false" if test "$PDFLATEX" = false -a "$PS2PDF" != false; then { $as_echo "$as_me:${as_lineno-$LINENO}: Alternative PDF generation via ps2pdf available." >&5 $as_echo "$as_me: Alternative PDF generation via ps2pdf available." >&6;} fi for ac_prog in dvipdfmx dvipdfm dvipdf do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DVIPDF+:} false; then : $as_echo_n "(cached) " >&6 else case $DVIPDF in [\\/]* | ?:[\\/]*) ac_cv_path_DVIPDF="$DVIPDF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DVIPDF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DVIPDF=$ac_cv_path_DVIPDF if test -n "$DVIPDF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DVIPDF" >&5 $as_echo "$DVIPDF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DVIPDF" && break done test -n "$DVIPDF" || DVIPDF="false" if test "$PDFLATEX" = false -a "$DVIPDF" != false; then { $as_echo "$as_me:${as_lineno-$LINENO}: Alternative PDF generation via dvipdf available." >&5 $as_echo "$as_me: Alternative PDF generation via dvipdf available." >&6;} fi if test "$can_build_doc" = yes; then BUILD_DOC_TRUE= BUILD_DOC_FALSE='#' else BUILD_DOC_TRUE='#' BUILD_DOC_FALSE= fi if test "$can_build_doc" = no; then no_doc_reason=", because of missing$missing_for_doc" fi DYNAMIC_TEX_PREAMBLE=\\def\\finishdynamicpreamble{\\relax} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable debugging" >&5 $as_echo_n "checking whether to enable debugging... " >&6; } debug_default="no" # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; enable_debug=$enableval else enable_debug=$debug_default fi if test "$enable_debug" = yes; then CXXFLAGS="$CXXFLAGS -g -DDEBUG" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } enable_debug=yes else CXXFLAGS="$CXXFLAGS -O2 -DNDEBUG" { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } enable_debug=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable image cache" >&5 $as_echo_n "checking whether to enable image cache... " >&6; } image_cache_default="no" # Check whether --enable-image_cache was given. if test "${enable_image_cache+set}" = set; then : enableval=$enable_image_cache; enable_image_cache=$enableval else enable_image_cache=$image_cache_default fi if test "$enable_image_cache" = yes; then $as_echo "#define CACHE_IMAGES 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } enable_image_cache=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } enable_image_cache=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to compile with OpenMP" >&5 $as_echo_n "checking whether to compile with OpenMP... " >&6; } openmp_default="no" # Check whether --enable-openmp was given. if test "${enable_openmp+set}" = set; then : enableval=$enable_openmp; enable_openmp=$enableval else enable_openmp=$openmp_default fi if test "$enable_openmp" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenMP flag of C++ compiler" >&5 $as_echo_n "checking for OpenMP flag of C++ compiler... " >&6; } if ${ax_cv_cxx_openmp+:} false; then : $as_echo_n "(cached) " >&6 else saveCXXFLAGS=$CXXFLAGS ax_cv_cxx_openmp=unknown # Flags to try: -fopenmp (gcc), -openmp (icc), -mp (SGI & PGI), # -xopenmp (Sun), -omp (Tru64), -qsmp=omp (AIX), none ax_openmp_flags="-fopenmp -openmp -mp -xopenmp -omp -qsmp=omp none" if test "x$OPENMP_CXXFLAGS" != x; then ax_openmp_flags="$OPENMP_CXXFLAGS $ax_openmp_flags" fi for ax_openmp_flag in $ax_openmp_flags; do case $ax_openmp_flag in none) CXXFLAGS=$saveCXX ;; *) CXXFLAGS="$saveCXXFLAGS $ax_openmp_flag" ;; esac cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char omp_set_num_threads (); int main () { return omp_set_num_threads (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ax_cv_cxx_openmp=$ax_openmp_flag; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done CXXFLAGS=$saveCXXFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_openmp" >&5 $as_echo "$ax_cv_cxx_openmp" >&6; } if test "x$ax_cv_cxx_openmp" = "xunknown"; then : else if test "x$ax_cv_cxx_openmp" != "xnone"; then OPENMP_CXXFLAGS=$ax_cv_cxx_openmp fi enable_openmp=yes fi CFLAGS="$CFLAGS $OPENMP_CFLAGS" CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" fi if test -z "$OPENMP_CXXFLAGS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } enable_openmp=no else if test "$enable_image_cache" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: image cache and OpenMP support are mutually exclusive" >&5 $as_echo "$as_me: WARNING: image cache and OpenMP support are mutually exclusive" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: only configure like this if you want to develop a reentrant image cache" >&5 $as_echo "$as_me: WARNING: only configure like this if you want to develop a reentrant image cache" >&2;} warnings=`echo -e "$warnings\n WARNING: Image cache and OpenMP are both enabled! You are a developer, aren't you?"` fi enable_openmp=yes fi ac_config_files="$ac_config_files doc/Makefile doc/examples/Makefile doc/examples/enfuse/Makefile doc/examples/enfuse/Makefile.userweight" ac_config_files="$ac_config_files Makefile src/Makefile src/dynamic_loader/Makefile src/layer_selection/Makefile src/win32helpers/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${DYNAMIC_EXPOSURE_WEIGHTS_TRUE}" && test -z "${DYNAMIC_EXPOSURE_WEIGHTS_FALSE}"; then as_fn_error $? "conditional \"DYNAMIC_EXPOSURE_WEIGHTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_DOC_TRUE}" && test -z "${BUILD_DOC_FALSE}"; then as_fn_error $? "conditional \"BUILD_DOC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by enblend-enfuse $as_me 4.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to . enblend-enfuse home page: <4.2>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ enblend-enfuse config.status 4.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "doc/examples/Makefile") CONFIG_FILES="$CONFIG_FILES doc/examples/Makefile" ;; "doc/examples/enfuse/Makefile") CONFIG_FILES="$CONFIG_FILES doc/examples/enfuse/Makefile" ;; "doc/examples/enfuse/Makefile.userweight") CONFIG_FILES="$CONFIG_FILES doc/examples/enfuse/Makefile.userweight" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/dynamic_loader/Makefile") CONFIG_FILES="$CONFIG_FILES src/dynamic_loader/Makefile" ;; "src/layer_selection/Makefile") CONFIG_FILES="$CONFIG_FILES src/layer_selection/Makefile" ;; "src/win32helpers/Makefile") CONFIG_FILES="$CONFIG_FILES src/win32helpers/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: enblend-enfuse now configured for ${host} Source directory: ${srcdir} Installation directory: ${prefix} C++ compiler: ${CXX} CFLAGS: ${CFLAGS:-} CXXFLAGS: ${CXXFLAGS:-} LDFLAGS: ${LDFLAGS:-} LIBS: ${LIBS:-} EXTRA_LIBS (optional): ${EXTRA_LIBS:-} can build all documentation: ${can_build_doc}${no_doc_reason} feature selection: enable debugging support: ${enable_debug} enable malloc debugging: ${enable_dmalloc} enable dynamic loading ${enable_dynload} ${dynload_implementation} OpenEXR image format ${have_exr} use image cache: ${enable_image_cache} use OpenMP: ${enable_openmp} use TCMalloc: ${use_tcmalloc} ${warnings}" >&5 $as_echo " enblend-enfuse now configured for ${host} Source directory: ${srcdir} Installation directory: ${prefix} C++ compiler: ${CXX} CFLAGS: ${CFLAGS:-} CXXFLAGS: ${CXXFLAGS:-} LDFLAGS: ${LDFLAGS:-} LIBS: ${LIBS:-} EXTRA_LIBS (optional): ${EXTRA_LIBS:-} can build all documentation: ${can_build_doc}${no_doc_reason} feature selection: enable debugging support: ${enable_debug} enable malloc debugging: ${enable_dmalloc} enable dynamic loading ${enable_dynload} ${dynload_implementation} OpenEXR image format ${have_exr} use image cache: ${enable_image_cache} use OpenMP: ${enable_openmp} use TCMalloc: ${use_tcmalloc} ${warnings}" >&6; } enblend-enfuse-4.2/CMakeLists.txt0000644000175000017500000004453012676263420013750 00000000000000# This file is part of enblend/enfuse. # Licence details can be found in the file COPYING. # # Copyright(c) 2009-2015, Kornel Benko # , Ryan Sleevi # , Harry van der Wolf # Original file from lyx-project, heavily modified # cmake_minimum_required(VERSION 2.8) set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) project(enblend) IF(NOT MSVC) SET(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel" FORCE) ENDIF(NOT MSVC) # where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ # is checked # For now, reuse the hugin modules directory # # Try to find ... set(CMAKE_MODULE_PATH) # overwrite cache find_file(CMAKE_MODULE_PATH CMakeModules "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/../hugin" "${CMAKE_SOURCE_DIR}/../hugin-trunk" "${CMAKE_SOURCE_DIR}/../../hugin/hugin" "${CMAKE_SOURCE_DIR}/../../hugin/trunk" "$ENV{HOME}/hugin") message(STATUS "found hugin modules directory in ${CMAKE_MODULE_PATH}") set(ARCH_TRIPLET) if(UNIX) FIND_PROGRAM(DPKG_ARCHITECTURE_EXECUTABLE dpkg-architecture) if(DPKG_ARCHITECTURE_EXECUTABLE) EXECUTE_PROCESS(COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH OUTPUT_VARIABLE ARCH_TRIPLET ERROR_VARIABLE ERROR_ARCH_TRIPLET OUTPUT_STRIP_TRAILING_WHITESPACE) endif() endif() if(ARCH_TRIPLET) set(SYSTEM_LIB_DIRS /usr/lib /usr/lib/${ARCH_TRIPLET} /usr/local/lib) else() set(SYSTEM_LIB_DIRS /usr/lib /usr/local/lib) endif() include(HuginMacros) include(FindLibraryForCPU) set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) # Regenerate when calling make set(CMAKE_SUPPRESS_REGENERATION FALSE) set(VERSION_INFO "CMake Build") # Try to get the package version from file set(TOP_SRC_DIR ${CMAKE_SOURCE_DIR}) file(STRINGS "${TOP_SRC_DIR}/VERSION" _version_lines) foreach(_v_l ${_version_lines}) if(_v_l MATCHES "^\([0-9]+\)\\.\([0-9]+\)\(.*\)") set(ENBLEND_MAJOR_VERSION ${CMAKE_MATCH_1}) set(ENBLEND_MINOR_VERSION ${CMAKE_MATCH_2}) set(_tmp ${CMAKE_MATCH_3}) if(_tmp MATCHES "^\\.\([0-9]+\)\(.*\)") set(ENBLEND_PATCH_VERSION ${CMAKE_MATCH_1}) set(_tmp ${CMAKE_MATCH_2}) else() set(ENBLEND_PATCH_VERSION "0") endif() set(PACKAGE_VERSION_STRING ${_v_l}) set(PACKAGE_URL "http://sourceforge.net/projects/enblend/files/enblend-enfuse/enblend-enfuse-${ENBLEND_MAJOR_VERSION}.${ENBLEND_MINOR_VERSION}/") break() endif() endforeach(_v_l) message(STATUS "Extracted enblend version = ${ENBLEND_MAJOR_VERSION}.${ENBLEND_MINOR_VERSION}.${ENBLEND_PATCH_VERSION}") # For Win32 builds, assume that all of the libraries are located # one directory above the current CMakeLists directory IF(WIN32) STRING(REGEX REPLACE "(.*)/[^/]+$" "\\1" work "${CMAKE_SOURCE_DIR}") # create the cache entry SET(SOURCE_BASE_DIR ${work} CACHE FILEPATH "parent dir of hugin source root") LIST(APPEND CMAKE_PREFIX_PATH ${SOURCE_BASE_DIR}) ENDIF(WIN32) # First include so it picks up(our) config.h INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}) SET(library_type STATIC) set(common_libs) IF(WIN32) # we are using static vigra lib on Windows ADD_DEFINITIONS(-DVIGRA_STATIC_LIB) ENDIF(WIN32) # Configurable options OPTION(ENABLE_OPENMP "OpenMP Support" OFF) OPTION(ENABLE_TCMALLOC "TCmalloc Support" OFF) IF(NOT WIN32) # dynamic loading on windows is supported by own class OPTION(ENABLE_DLOPEN "Dlopen Support" ON) ENDIF() OPTION(DOC "Create Documentation" OFF) IF(NOT CMAKE_CL_64) OPTION(ENABLE_SSE2 "SSE2 Support(Release builds only)" OFF) ELSE(NOT CMAKE_CL_64) SET(ENABLE_SSE2 OFF CACHE INTERNAL "") ENDIF(NOT CMAKE_CL_64) IF(NOT WIN32) OPTION(ENABLE_DMALLOC "Use the dmalloc debugging package" OFF) OPTION(ENABLE_DMALLOC_FUNC_CHECK "Enable dmalloc function checking" OFF) ELSE(NOT WIN32) SET(ENABLE_DMALLOC OFF CACHE INTERNAL "") SET(ENABLE_DMALLOC_FUNC_CHECK OFF CACHE INTERNAL "") ENDIF(NOT WIN32) # Compiler specific tweaks and optimizations # Microsoft Visual C++ compiler does not need any addtional switches for C++11 # so check only other compilers IF (NOT MSVC) FIND_PACKAGE(CXX11Compiler) IF(NOT CXX11COMPILER_FOUND) MESSAGE(FATAL_ERROR "A C++11 compatible compiler is required.") ENDIF() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_FLAG}") ENDIF() IF(CMAKE_COMPILER_IS_GNUCXX) SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -ffast-math -DNDEBUG -Wall") IF(APPLE AND CMAKE_MAJOR_VERSION EQUAL 2 AND CMAKE_MINOR_VERSION LESS 5) ## Add needed Compiler and Linker flags for OSX SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flat_namespace -undefined suppress") SET(CMAKE_CXX_FLAGS "{$CMAKE_CXX_FLAGS} -flat_namespace -undefined suppress") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flat_namespace -undefined suppress") SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -flat_namespace -undefined suppress") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -flat_namespace -undefined suppress") ENDIF(APPLE AND CMAKE_MAJOR_VERSION EQUAL 2 AND CMAKE_MINOR_VERSION LESS 5) ELSEIF(WIN32) IF(MSVC) # Quiet some compiler noise ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE) ADD_DEFINITIONS(-D_SCL_SECURE_NO_WARNINGS) ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_DEPRECATE) # Due to the number of templates and the added overhead in .obj files from 64-bit builds # add /bigobj support # details: http://msdn.microsoft.com/en-us/library/ms173499.aspx IF(CMAKE_CL_64) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /bigobj") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") ENDIF(CMAKE_CL_64) # compile everything for the static C runtime FOREACH(TYPE C CXX) # makefiles use blank configuration FOREACH(CFG "_DEBUG" "_MINSIZEREL" "_RELEASE" "_RELWITHDEBINFO") #MESSAGE("Replacing CMAKE_${TYPE}_FLAGS${CFG}: ${CMAKE_${TYPE}_FLAGS${CFG}}") SET(NEW_FLAGS "${CMAKE_${TYPE}_FLAGS${CFG}}") # fix up static libc flags STRING(REPLACE "/MD" "/MT" NEW_FLAGS "${NEW_FLAGS}") # *FORCE* to override whats already placed into the cache SET(CMAKE_${TYPE}_FLAGS${CFG} "${NEW_FLAGS}" CACHE STRING "CMAKE_${TYPE}_FLAGS${CFG} (overwritten to ensure static build)" FORCE) #MESSAGE("New CMAKE_${TYPE}_FLAGS${CFG}: ${CMAKE_${TYPE}_FLAGS${CFG}}") ENDFOREACH(CFG) ENDFOREACH(TYPE) # link only with the static C runtime !! THIS IS A MUST !! SET(NEW_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") # ensure that the flags are not duplicated on subsequent runs STRING(REPLACE " /NODEFAULTLIB:\"MSVCRT.lib\" /NODEFAULTLIB:\"MSVCRTd.lib\" /LTCG /LARGEADDRESSAWARE" "" NEW_FLAGS "${NEW_FLAGS}") # note that flag names (NODEFAULTLIB) etc.) are case sensitive SET( CMAKE_EXE_LINKER_FLAGS "${NEW_FLAGS} /NODEFAULTLIB:\"MSVCRT.lib\" /NODEFAULTLIB:\"MSVCRTd.lib\" /LTCG /LARGEADDRESSAWARE" CACHE STRING "for MSVC" FORCE ) # Maximize speed STRING(REPLACE " /O2 " " /Ox /GL " CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") STRING(REPLACE " /O2 " " /Ox /GL " CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") SET(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /GL") ENDIF(MSVC) ENDIF(CMAKE_COMPILER_IS_GNUCXX) # Required Libraries first FIND_PACKAGE(LCMS2 REQUIRED) ADD_DEFINITIONS(-DHAVE_LIBLCMS2) FIND_PACKAGE(TIFF REQUIRED) FIND_PACKAGE(Perl REQUIRED) # this one is needed in doc. (Especially the program "convert") FIND_PACKAGE(GSL REQUIRED) include_directories(${GSL_INCLUDE_DIR}) ADD_DEFINITIONS(-DHAVE_LIBGSL) ADD_DEFINITIONS(-DHAVE_LIBGSLCBLAS) LIST(APPEND common_libs ${LCMS2_LIBRARIES} ${TIFF_LIBRARIES} ${GSL_LIBRARIES}) include_directories(${TIFF_INCLUDE_DIR} ${LCMS2_INCLUDE_DIR}) # Platform specifics required libraries IF(WIN32) SET(Boost_USE_STATIC_LIBS ON) # path for getopt library INCLUDE_DIRECTORIES(${TOP_SRC_DIR}/src/win32helpers) ENDIF(WIN32) # Boost headers are required, but filesystem is optional if(WIN32) IF( NOT Boost_root_suffix ) SET( Boost_root_suffix _1_51_0 CACHE STRING "suffix of boost root dir." FORCE ) ENDIF( NOT Boost_root_suffix ) SET(Boost_USE_STATIC_LIBS ON) if (NOT BOOST_ROOT AND NOT $ENV{BOOST_ROOT} STREQUAL "") set(BOOST_ROOT $ENV{BOOST_ROOT}) else(NOT BOOST_ROOT AND NOT $ENV{BOOST_ROOT} STREQUAL "") set(BOOST_ROOT ${SOURCE_BASE_DIR}/boost${Boost_root_suffix}) endif(NOT BOOST_ROOT AND NOT $ENV{BOOST_ROOT} STREQUAL "") endif() # Boost headers are required FIND_PACKAGE(Boost 1.55 REQUIRED) #check some header and functions include(ConfigureChecks.cmake) include_directories(${Boost_INCLUDE_DIR}) # Optional Libraries FIND_PACKAGE(ZLIB) FIND_PACKAGE(JPEG) FIND_PACKAGE(PNG) FIND_PACKAGE(OpenEXR) FIND_PACKAGE(Threads) # VIGRA uses Has* pre-processor definitions for config.h ADD_DEFINITIONS(-DHasTIFF) FIND_PACKAGE(VIGRA REQUIRED) include_directories(${VIGRA_INCLUDE_DIR}) list(APPEND common_libs ${VIGRA_LIBRARIES}) IF(ZLIB_FOUND) LIST(APPEND common_libs ${ZLIB_LIBRARIES}) include_directories(${ZLIB_INCLUDE_DIR}) ADD_DEFINITIONS(-DHAVE_LIBZ) ELSEIF(WIN32) IF(PNG_FOUND) MESSAGE(STATUS "Disabling support for PNG due to lack of zlib") SET(PNG_FOUND 0) ENDIF(PNG_FOUND) ENDIF(ZLIB_FOUND) IF(JPEG_FOUND) ADD_DEFINITIONS(-DHasJPEG) list(APPEND common_libs ${JPEG_LIBRARIES}) include_directories(${JPEG_INCLUDE_DIR}) ELSE(JPEG_FOUND) MESSAGE(STATUS "Compiling without support for JPEG files") ENDIF(JPEG_FOUND) IF(PNG_FOUND) ADD_DEFINITIONS(-DHasPNG) list(APPEND common_libs ${PNG_LIBRARIES}) include_directories(${PNG_INCLUDE_DIR}) ELSE(PNG_FOUND) MESSAGE(STATUS "Compiling without support for PNG files") ENDIF(PNG_FOUND) IF(OPENEXR_FOUND) ADD_DEFINITIONS(-DHasEXR) list(APPEND common_libs ${OPENEXR_LIBRARIES}) include_directories(${OPENEXR_INCLUDE_DIR}) ELSE(OPENEXR_FOUND) MESSAGE(STATUS "OpenEXR support disabled") ENDIF(OPENEXR_FOUND) # Now that packages are / are not detected, handle config options IF(ENABLE_OPENMP) FIND_PACKAGE(OpenMP REQUIRED) add_definitions(${OpenMP_CXX_FLAGS}) ENDIF(ENABLE_OPENMP) IF(ENABLE_SSE2) set_sse_cxx_flags() ENDIF(ENABLE_SSE2) IF(ENABLE_DMALLOC) ADD_DEFINITIONS(-DDMALLOC) IF(ENABLE_DMALLOC_FUNC_CHECK) ADD_DEFINITIONS(-DDMALLOC_FUNC_CHECK) ENDIF(ENABLE_DMALLOC_FUNC_CHECK) IF(CMAKE_USE_PTHREADS_INIT) FIND_LIBRARY(dmalloc_LIBRARIES dmallocthcxx) ELSE(CMAKE_USE_PTHREADS_INIT) FIND_LIBRARY(dmalloc_LIBRARIES dmalloccxx) ENDIF(CMAKE_USE_PTHREADS_INIT) IF(NOT dmalloc_LIBRARIES) MESSAGE(FATAL_ERROR "dmalloc support requested, but was unable to locate dmalloc library") ENDIF(NOT dmalloc_LIBRARIES) add_definitions("-g") LIST(APPEND common_libs ${dmalloc_LIBRARIES}) ENDIF(ENABLE_DMALLOC) if(ENABLE_TCMALLOC) find_package(TCmalloc REQUIRED) add_definitions("-DHAVE_TCMALLOC") add_definitions("-DHAVE_TCMALLOC_H") include_directories(${TCMALLOC_INCLUDE_DIR}) LIST(APPEND common_libs ${TCMALLOC_LIBRARIES}) endif() if(ENABLE_DLOPEN) find_package(Dlopen REQUIRED) list(APPEND common_libs ${DLOPEN_LIBRARIES}) set(HAVE_DL 1) endif() # Try to create config.h set(ENBLEND_VERSION_ONLY "${PACKAGE_VERSION_STRING}") set(PACKAGE_STRING "enblend-enfuse ${ENBLEND_VERSION_ONLY}") set(ENBLEND_VERSION "${PACKAGE_STRING}") configure_file(config.h.cmake ${CMAKE_BINARY_DIR}/config.h) add_definitions(-DHAVE_CONFIG_H) include_directories(${CMAKE_BINARY_DIR}) # check dependencies for build doc if (PERL_FOUND AND DOC) option(INSTALL_PS_DOC "Install documentation in postscript format" ON) option(INSTALL_PDF_DOC "Install documentation in pdf format" OFF) option(INSTALL_HTML_DOC "Install documentation in html format" OFF) if(NOT INSTALL_PS_DOC AND NOT INSTALL_PDF_DOC AND NOT INSTALL_HTML_DOC) message(FATAL_ERROR "You selected to build documentation, but selected no format for installation. This is not supported.") endif() find_package(ImageMagick COMPONENTS convert REQUIRED) if(INSTALL_PS_DOC) if(INSTALL_PDF_DOC) # PS + PDF find_package(LATEX COMPONENTS DVIPS PDFLATEX MAKEINDEX REQUIRED) else() # only PS find_package(LATEX COMPONENTS DVIPS MAKEINDEX REQUIRED) endif() else() if(INSTALL_PDF_DOC) # only PDF find_package(LATEX COMPONENTS PDFLATEX MAKEINDEX REQUIRED) endif() endif() find_package(Gnuplot REQUIRED) set(_x86 "(x86)") file(GLOB _GRAPHVIZ_BIN_DIRS "$ENV{ProgramFiles}/Graphviz*/bin" "$ENV{ProgramFiles${_x86}}/Graphviz*/bin" ) unset(_x86) find_program(DOT_EXECUTABLE NAMES dot PATHS ${_GRAPHVIZ_BIN_DIRS} [HKEY_LOCAL_MACHINE\\SOFTWARE\\ATT\\Graphviz;InstallPath]/bin /Applications/Graphviz.app/Contents/MacOS /Applications/Doxygen.app/Contents/Resources /Applications/Doxygen.app/Contents/MacOS DOC "Graphviz Dot tool" ) if (${DOT_EXECUTABLE} MATCHES "-NOTFOUND") message(FATAL_ERROR "Program dot from graphviz not found. This program is required to build the documentation.") endif() find_program(M4_EXECUTABLE m4) if(${M4_EXECUTABLE} MATCHES "-NOTFOUND") message(FATAL_ERROR "Program m4 not found. This program is required to build the documentation.") endif() find_program(RSVGCONVERT_EXECUTABLE rsvg-convert) if(${RSVGCONVERT_EXECUTABLE} MATCHES "-NOTFOUND") message(FATAL_ERROR "Program rsvg-convert not found. This program is required to build the documentation.") endif() find_program(HEVEA_EXE hevea) if (${HEVEA_EXE} MATCHES "-NOTFOUND") message(FATAL_ERROR "Program hevea not found. This program is required to build the documentation.") endif() execute_process( COMMAND ${HEVEA_EXE} -version OUTPUT_VARIABLE _HEVEA_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) if(WIN32) # on Windows hevea report always c:\hevea as lib dir # so assume the necessary files are beside the executable get_filename_component(HEVEA_LIB_DIR ${HEVEA_EXE} PATH) else() execute_process( COMMAND ${HEVEA_EXE} -version OUTPUT_VARIABLE _HEVEA_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) if(${_HEVEA_VERSION} MATCHES "library directory:[ \t]*(.*)$") set(HEVEA_LIB_DIR ${CMAKE_MATCH_1}) string(REGEX REPLACE "\\\\" "/" HEVEA_LIB_DIR ${HEVEA_LIB_DIR}) message(STATUS "Hevea library directory: ${HEVEA_LIB_DIR}") else() message(FATAL_ERROR "Could not retrieve hevea library directory.") endif() endif() # checking for required Perl module Readonly execute_process( COMMAND "${PERL_EXECUTABLE}" "-e" "use Readonly; print \$INC{\"Readonly\"}" RESULT_VARIABLE readonly_result_code ) if(NOT readonly_result_code EQUAL 0) message(FATAL_ERROR "Checking for perl module Readonly - failed") endif() set(PAPERSIZE "a4" CACHE STRING "Papersize for some converters: a4, a5, b5, executive, legal, letter") set(PRINTRESOLUTION "600" CACHE STRING "Resolution for some converters in dots-per-inch") set(DYNAMIC_TEX_PREAMBLE "\\def\\finishdynamicpreamble{\\relax}" CACHE STRING "LaTeX commands to add to preamble") endif() MESSAGE(STATUS "") MESSAGE(STATUS "") MESSAGE(STATUS "Enblend-enfuse now configured for ${CMAKE_SYSTEM}") MESSAGE(STATUS "Source Directory: ${CMAKE_SOURCE_DIR}") message(STATUS "Build Directory: ${CMAKE_BINARY_DIR}") message(STATUS "Installation Directory: ${CMAKE_INSTALL_PREFIX}") MESSAGE(STATUS "C++ Compiler: ${CMAKE_CXX_COMPILER}") MESSAGE(STATUS "CFLAGS: ${CMAKE_C_FLAGS}") MESSAGE(STATUS "CXXFLAGS: ${CMAKE_CXX_FLAGS}") MESSAGE(STATUS "Libraries: ${common_libs}") MESSAGE(STATUS "") MESSAGE(STATUS "Features Enabled:") IF(NOT WIN32) MESSAGE(STATUS "enable malloc debugging: ${ENABLE_DMALLOC}") ENDIF(NOT WIN32) MESSAGE(STATUS "use OpenMP: ${ENABLE_OPENMP}") MESSAGE(STATUS "use TCmalloc: ${ENABLE_TCMALLOC}") MESSAGE(STATUS "") MESSAGE(STATUS "Image Formats Enabled:") MESSAGE(STATUS "OpenEXR: ${OPENEXR_FOUND}") MESSAGE(STATUS "JPEG: ${JPEG_FOUND}") MESSAGE(STATUS "TIFF: ${TIFF_FOUND}") MESSAGE(STATUS "PNG: ${PNG_FOUND}") MESSAGE(STATUS "") MESSAGE(STATUS ${WARNINGS}) MESSAGE(STATUS "") add_subdirectory(src) # create doc's if (PERL_FOUND AND DOC) add_subdirectory(doc) endif() # Windows installer packaging related stuff # prepare files here... IF(WIN32) # install into place in build-dir SET( CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/INSTALL/FILES CACHE FILEPATH "install prefix" FORCE) SET( INSTALL_WIN_FILES AUTHORS ChangeLog COPYING NEWS README ) INSTALL(FILES ${INSTALL_WIN_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}) # install Eriks droplets SET( DROPLETS_FILES contrib/enfuse_droplet/enfuse_droplet.bat contrib/enfuse_droplet/enfuse_droplet_360.bat contrib/enfuse_droplet/enfuse_droplet_readme.txt contrib/enfuse_droplet/LICENCE.txt) INSTALL(FILES ${DROPLETS_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/droplets) ENDIF(WIN32) SET(CPACK_PACKAGE_VERSION_MAJOR ${ENBLEND_MAJOR_VERSION}) SET(CPACK_PACKAGE_VERSION_MINOR ${ENBLEND_MINOR_VERSION}) SET(CPACK_PACKAGE_VERSION_PATCH ${ENBLEND_PATCH_VERSION}) FIND_PROGRAM(ENBLEND_HG hg) if(ENBLEND_HG) execute_process(COMMAND ${ENBLEND_HG} summary WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE ENBLEND_TIP_OUT ERROR_VARIABLE ENBLEND_TIP_ERROR OUTPUT_STRIP_TRAILING_WHITESPACE) if(NOT ENBLEND_TIP_ERROR) STRING(REGEX REPLACE "\n" ";" ENBLEND_TIP_LINES ${ENBLEND_TIP_OUT}) foreach(_v_l ${ENBLEND_TIP_LINES}) if(_v_l MATCHES ".*:[ ]+\([0-9]+\):[0-9a-f]+") set(CPACK_PACKAGE_VERSION_PATCH "${ENBLEND_PATCH_VERSION}-${CMAKE_MATCH_1}hg") break() endif() endforeach() endif() endif() # Use dpkg-shlibs to get the dependences SET(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) # needed by rpm SET(CPACK_SET_DESTDIR "ON") # The next ones are required by debian SET(CPACK_PACKAGE_CONTACT "hugin-ptx@googlegroups.com") # ignore some directories when creating rpm SET(CPACK_RPM_SPEC_MORE_DEFINE "%define ignore \#") SET(CPACK_RPM_USER_FILELIST "%ignore /usr/local" "%ignore /usr/local/bin" "%ignore /usr/local/share" "%ignore /usr/local/share/man" "%ignore /usr/local/share/man/man1" ) include(CPack) enblend-enfuse-4.2/configure.ac0000644000175000017500000005373312676176342013511 00000000000000AC_PREREQ([2.69]) AC_INIT([enblend-enfuse], [m4_esyscmd([tr -d '\n' < VERSION])], [https://bugs.launchpad.net/enblend], [], [m4_esyscmd([sed -e 's,^\([^-]*\)-.*$,http://sourceforge.net/projects/enblend/files/enblend-enfuse/enblend-enfuse-\1/,' < VERSION | tr -d '\n'])]) AC_CONFIG_SRCDIR([src/enblend.cc]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_MACRO_DIR(m4) AC_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE([foreign no-installinfo]) AM_SILENT_RULES() AC_PROG_CXX AX_CXX_COMPILE_STDCXX_11(ext) AC_CXX_AS_CONST AC_PROG_CC AC_PROG_AR AM_PROG_AR AC_PROG_EGREP AC_PROG_GREP AC_PROG_RANLIB AC_PROG_SED AC_LANG(C++) AC_C_BIGENDIAN enable_on_demand_dynamic_linking=check AC_MSG_CHECKING([if on-demand dynamic linking is desired]) AC_ARG_ENABLE([on-demand-dynlink], [AS_HELP_STRING([--enable-on-demand-dynlink], [use on-demand dynamic linking @<:@default=check@:>@])], [AC_MSG_RESULT($enableval); enable_on_demand_dynamic_linking=$enableval], [AC_MSG_RESULT(check); enable_on_demand_dynamic_linking=check]) have_on_demand_dynamic_linking=no AS_IF([test "$enable_on_demand_dynamic_linking" = no], [have_on_demand_dynamic_linking=no], [if test -n "$enable_on_demand_dynamic_linking" || \ test "$enable_on_demand_dynamic_linking" = yes || \ test "$enable_on_demand_dynamic_linking" = check; then AC_MSG_CHECKING([for on-demand dynamic linking]) save_ldflags="$LDFLAGS" LDFLAGS="-Wl,--as-needed -Wl,--no-copy-dt-needed-entries ${LDFLAGS}" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[strlen("foo")]])], [AC_MSG_RESULT(yes); have_on_demand_dynamic_linking=yes], AC_MSG_RESULT(no)) LDFLAGS="$save_ldflags" fi]) if test "$have_on_demand_dynamic_linking" = yes; then LDFLAGS="-Wl,--as-needed -Wl,--no-copy-dt-needed-entries ${LDFLAGS}" fi # Checks for libraries. # We check for TCMalloc so early to make it the last user library on # the linker command line. It will then gobble all undefined # references to malloc(3) and free(3) and thus relieve the O/S even # more. use_tcmalloc=no AC_ARG_WITH([tcmalloc], [AS_HELP_STRING([--with-tcmalloc], [use Google's TCMalloc library @<:@default=check@:>@])], [], [with_tcmalloc=check]) AS_IF([test "$with_tcmalloc" = check -o "$with_tcmalloc" = yes], [AC_CHECK_HEADERS([gperftools/tcmalloc.h tcmalloc.h], [break]) if test "$ac_cv_header_tcmalloc_h" = yes -o "$with_tcmalloc" = yes; then AC_SEARCH_LIBS(tc_malloc, [tcmalloc, tcmalloc_minimal], [use_tcmalloc=yes AC_DEFINE(HAVE_TCMALLOC, 1, [Define if you have Google's TCMalloc library])]) fi]) AC_CHECK_LIB([m], [sqrt]) AC_CHECK_LIB([gslcblas], [cblas_dgemm]) AC_CHECK_LIB([gsl], [gsl_blas_dgemm]) AC_CHECK_LIB(z, gzopen, [], AC_MSG_NOTICE([Compiling without libz.]), []) AC_CHECK_LIB(jpeg, jpeg_finish_compress, [LIBS="-ljpeg ${LIBS}"; AC_DEFINE(HasJPEG, 1, [Define if you have the jpeg library])], AC_MSG_NOTICE([Compiling without support for jpeg files.]), []) AC_CHECK_LIB(png, png_init_io, [LIBS="-lpng ${LIBS}"; AC_DEFINE(HasPNG, 1, [Define if you have the png library])], AC_MSG_NOTICE([Compiling without support for png files.]), []) AC_CHECK_LIB(tiff, TIFFOpen, [LIBS="-ltiff ${LIBS}"; AC_DEFINE(HasTIFF, 1, [Define if you have the tiff library])], AC_MSG_ERROR([libtiff is required to compile Enblend.]), []) AC_CHECK_LIB(lcms2, cmsCreateTransform, [], AC_MSG_ERROR([liblcms2 is required to compile Enblend.]), []) AC_MSG_CHECKING([if OpenEXR is wanted]) AC_ARG_WITH([openexr], [AS_HELP_STRING([--with-openexr], [use OpenEXR @<:@default=check@:>@])], [], [with_openexr=check]) AS_IF([test "$with_openexr" = no], [AC_MSG_NOTICE([disabling OpenEXR]) have_exr=no], [if test "$with_openexr" = yes || test "$with_openexr" = check; then AC_MSG_RESULT(yes) PKG_CHECK_MODULES(OPENEXR, OpenEXR >= 1.0, [AC_DEFINE(HasEXR, 1, [Define if you have EXR library]) have_exr=yes], [AC_MSG_WARN("OpenEXR support disabled: " $OPENEXR_PKG_ERRORS) have_exr=no]) LIBS="${OPENEXR_LIBS} $LIBS" CFLAGS="${OPENEXR_CFLAGS} $CFLAGS" CXXFLAGS="${OPENEXR_CFLAGS} $CXXFLAGS" else AC_MSG_RESULT(no) have_exr=no fi]) AC_ARG_VAR([VIGRAIMPEX_LIB], [name of Vigra import/export-library]) if test -z "$VIGRAIMPEX_LIB"; then VIGRAIMPEX_LIB='-lvigraimpex' fi AC_MSG_CHECKING([for Vigra import/export-library]) LIBS="$VIGRAIMPEX_LIB $LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[vigra::impexListFormats()]])], AC_MSG_RESULT(yes), [AC_MSG_RESULT(no) AC_MSG_ERROR([libvigraimpex is required to compile Enblend.])]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[vigra::BRGBImage image; vigra::BImage alpha; vigra::ImageImportInfo info("image.tif"); info.setImageIndex(99); vigra::importImageAlpha(info, destImage(image), destImage(alpha));]])], AC_MSG_RESULT(yes), [AC_MSG_RESULT(no) AC_MSG_ERROR([Vigra was found, but it was not recent enough.])]) # Memory allocation debug support AC_MSG_CHECKING([if malloc debugging is wanted]) AC_ARG_WITH(dmalloc, [ --with-dmalloc use dmalloc, as in http://www.dmalloc.com/dmalloc.tar.gz], [if test "$withval" = yes; then AC_MSG_RESULT(yes) AC_DEFINE(WITH_DMALLOC, 1, [Define if using the dmalloc debugging malloc package]) if test $acx_pthread_ok = yes; then LIBS="$LIBS -ldmallocthcxx" enable_dmalloc="yes (thread aware)" else LIBS="$LIBS -ldmalloccxx" enable_dmalloc=yes fi LDFLAGS="$LDFLAGS -g" AC_DEFINE(DMALLOC, 1, [Define to enable malloc debugger library]) AC_DEFINE(DMALLOC_FUNC_CHECK, 1, [Define to enable malloc debugger function checking]) else AC_MSG_RESULT(no) enable_dmalloc=no fi], [AC_MSG_RESULT(no) enable_dmalloc=no]) DL_IMPLEMENTATION='' dynload_implementation='' enable_dynload=no AC_ARG_WITH([dl], [AS_HELP_STRING([--with-dl], [add support for dynamic loading @<:@default=check@:>@])], [], [with_dl=check]) AS_IF([test "$with_dl" != no], [if test "$with_dl" = check -o "$with_dl" = yes -o "$with_dl" = dl; then AC_CHECK_HEADERS(dlfcn.h) if test "$ac_cv_header_dlfcn_h" = yes; then AC_SEARCH_LIBS(dlopen, [dl], [AC_DEFINE(HAVE_DL, 1, [Define if you have support for dynamic loading]) AC_DEFINE(POSIX_DL, 1, [Use POSIX dl implementation]) DL_IMPLEMENTATION='libdynamic_loader_a-posix_implementation.o' dynload_implementation='(via dl)' enable_dynload=yes]) fi fi if test "$enable_dynload" != yes -a \( "$with_dl" = check -o "$with_dl" = gmodule \); then AC_CHECK_HEADERS(gmodule.h) if test "$ac_cv_header_gmodule_h" = yes; then AC_SEARCH_LIBS(g_module_open, [gmodule-2.0], [AC_DEFINE(HAVE_DL, 1, [Define if you have support for dynamic loading]) AC_DEFINE(GMODULE_DL, 1, [Use gmodule-2.0 dl implementation]) DL_IMPLEMENTATION='libdynamic_loader_a-gmodule_implementation.o' dynload_implementation='(via gmodule-2.0)' enable_dynload=yes]) fi fi]) AC_SUBST(DL_IMPLEMENTATION) AM_CONDITIONAL([DYNAMIC_EXPOSURE_WEIGHTS], [test "$enable_dynload" = yes]) # Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC AC_CHECK_HEADERS([fenv.h limits.h stdlib.h string.h unistd.h]) AC_CHECK_HEADER([sys/times.h], [AC_DEFINE([HAVE_SYS_TIMES_H], [1], [Define if exists.])]) AC_CHECK_HEADER(tiffio.h, [], AC_MSG_ERROR([libtiff-devel header files are required to compile Enblend.])) AC_CHECK_HEADER(jpeglib.h, [], AC_MSG_ERROR([libjpeg-devel header files are required to compile Enblend.])) AC_CHECK_HEADER(png.h, [], AC_MSG_ERROR([libpng-devel header files are required to compile Enblend.])) AC_LANG_PUSH([C++]) AC_CHECK_HEADER(vigra/basicimage.hxx, [], AC_MSG_ERROR([Vigra "basicimage.hxx" header file is required to compile Enblend.])) AX_BOOST_BASE([1.55], [], AC_MSG_ERROR([Boost version 1.55 or later is required to compile Enblend.])) AC_CHECK_HEADER(boost/optional.hpp, [], AC_MSG_ERROR([Boost "optional" header file is required to compile Enblend.])) AC_CHECK_HEADER(gsl/gsl_errno.h, [], AC_MSG_ERROR([GNU Scientific Library (GSL) header file "gsl_errno" is required to compile Enblend.])) AC_CHECK_HEADER(gsl/gsl_min.h, [], AC_MSG_ERROR([GNU Scientific Library (GSL) header file "gsl_min" is required to compile Enblend.])) AC_CHECK_HEADER(gsl/gsl_multimin.h, [], AC_MSG_ERROR([GNU Scientific Library (GSL) header file "gsl_multimin" is required to compile Enblend.])) AC_CHECK_HEADER(gsl/gsl_rng.h, [], AC_MSG_ERROR([GNU Scientific Library (GSL) header file "gsl_rng" is required to compile Enblend.])) AC_CHECK_HEADER(gsl/gsl_vector.h, [], AC_MSG_ERROR([GNU Scientific Library (GSL) header file "gsl_vector" is required to compile Enblend.])) AC_LANG_POP([]) AC_SUBST(EXTRA_LIBS) AC_CHECK_HEADER(lcms2.h, [], AC_MSG_ERROR([lcms2 header files are required to compile Enblend.])) # Checks for typedefs, structures, and compiler characteristics. AC_CHECK_HEADER_STDBOOL AC_C_CONST AC_C_INLINE if test "$ac_cv_c_inline" != no; then AC_DEFINE(HAVE_INLINE, 1, [Define if functions can be declared `inline'.]) AC_SUBST(HAVE_INLINE) fi AC_C_RESTRICT AC_DEFINE([RESTRICT], [restrict], [Map RESTRICT onto C99 restrict keyword]) AC_TYPE_OFF_T AC_TYPE_SIG_ATOMIC_T AC_TYPE_SIZE_T AC_CHECK_TYPES([ptrdiff_t]) # Checks for library functions. AC_FUNC_CLOSEDIR_VOID AC_FUNC_ERROR_AT_LINE AC_FUNC_FSEEKO AC_FUNC_SETVBUF_REVERSED AC_FUNC_STRERROR_R AC_FUNC_STRTOD AC_CHECK_FUNCS([atexit clock_gettime \ fesetround floor \ memset mkstemp select \ pow sqrt \ sqrt strchr strcspn strdup strerror strpbrk strrchr strtok_r strtol strtoul]) # lrint and lrintf AC_C99_FUNC_LRINT AC_C99_FUNC_LRINTF AC_MSG_CHECKING([for BOOST_FALLTHROUGH]) AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include ]], [[BOOST_FALLTHROUGH]])], [ac_found=yes; AC_MSG_RESULT([yes])], [ac_found=no]; AC_MSG_RESULT([no])) if test "$ac_found" = no; then AC_DEFINE(BOOST_FALLTHROUGH, [((void) 0)], [Define if Boost is not recent enough to define BOOST_FALLTHROUGH itself]) fi AC_PATH_PROG(PERL, perl, false) if test "$PERL" = false; then AC_MSG_ERROR(cannot find perl) fi AX_PROG_PERL_MODULES(Sys::Hostname, [], AC_MSG_ERROR(missing Perl module Sys::Hostname)) AX_PROG_PERL_MODULES(Time::Zone, [], AC_MSG_WARN(missing Perl module Time::Zone)) # Documentation if test "$cross_compiling" = no; then AM_MISSING_PROG(HELP2MAN, help2man) else HELP2MAN=: fi can_build_doc=yes AC_PATH_PROGS(LATEX, [latex elatex lambda], [AC_MSG_WARN(missing LaTeX translator) can_build_doc=no missing_for_doc="$missing_for_doc latex"]) AC_PATH_PROG(PDFLATEX, pdflatex, [AC_MSG_WARN([missing PDFLaTeX translator -- no direct translation of LaTeX to PDF available]) missing_for_doc="$missing_for_doc pdflatex"]) if test "$latex" != 'no' then AC_LATEX_CLASS(report,report,[], [AC_MSG_WARN(missing document class report.cls) can_build_doc=no missing_for_doc="$missing_for_doc report.cls"]) AC_LATEX_CLASS(refrep,refrep,[], [AC_MSG_WARN([missing document class refrep.cls -- no Reference Manual Style available]) missing_for_doc="$missing_for_doc refrep.cls"]) dnl FIXME: We ought to add package `hypcap' to the list, but dnl `AC_LATEX_PACKAGE' does not allow for prerequisite pqckages to be dnl mentioned while testing and `hypcap' needs `hyperref' to be dnl included first. m4_foreach([package_name], [amsmath, bold-extra, color, enumitem, float, footnote, graphicx, hyperref, hyphenat, ifpdf, index, latexsym, listings, microtype, ragged2e, shorttoc, suffix, url, xstring], [AC_LATEX_PACKAGE([package_name], [report], [m4_translit(package_name,[-],[_])], [], [AC_MSG_WARN(missing LaTeX package package_name) can_build_doc=no missing_for_doc="$missing_for_doc package_name.sty"])]) fi if test "$PERL" != false; then AX_PROG_PERL_MODULES(File::Basename, [], [AC_MSG_WARN(missing Perl module File::Basename) can_build_doc=no missing_for_doc="$missing_for_doc File::Basename"]) AX_PROG_PERL_MODULES(FindBin, [], [AC_MSG_WARN(missing Perl module FindBin) can_build_doc=no missing_for_doc="$missing_for_doc FindBin"]) AX_PROG_PERL_MODULES(Getopt::Long, [], [AC_MSG_WARN(missing Perl module Getopt::Long) can_build_doc=no missing_for_doc="$missing_for_doc Getopt::Long"]) AX_PROG_PERL_MODULES(IO::File, [], [AC_MSG_WARN(missing Perl module IO::File) can_build_doc=no missing_for_doc="$missing_for_doc IO::File"]) AX_PROG_PERL_MODULES(IO::Handle, [], [AC_MSG_WARN(missing Perl module IO::Handle) can_build_doc=no missing_for_doc="$missing_for_doc IO::Handle"]) AX_PROG_PERL_MODULES(Readonly, [], [AC_MSG_WARN(missing Perl module Readonly) can_build_doc=no missing_for_doc="$missing_for_doc Readonly"]) fi AC_PATH_PROG(TEXLOGANALYSER, texloganalyser, cat) if test "$TEXLOGANALYSER" = cat; then AC_MSG_WARN([cannot find texloganalyser; will substitute cat(1)]) missing_for_doc="$missing_for_doc texloganalyser" fi AC_PATH_PROG(MAKEINDEX, makeindex, false) if test "$MAKEINDEX" = false; then AC_MSG_WARN(cannot find makeindex; will not be able to build documentation with index) can_build_doc=no missing_for_doc="$missing_for_doc makeindex" fi AC_PATH_PROG(DVIPS, dvips, false) if test "$DVIPS" = false; then AC_MSG_WARN(cannot find dvips; will not be able to build PostScript documentation) can_build_doc=no missing_for_doc="$missing_for_doc dvips" fi AC_PATH_PROG(CONVERT, convert, false) if test "$CONVERT" = false; then AC_MSG_WARN(cannot find convert; will not be able to build documentation) can_build_doc=no missing_for_doc="$missing_for_doc convert" fi AX_WITH_PROG(LATEX2HTML, hevea, false, []) if test "$LATEX2HTML" = false; then AC_MSG_WARN(cannot find LaTeX to HTML translator; will not be able to build HTML documentation) can_build_doc=no missing_for_doc="$missing_for_doc hevea" else AC_MSG_CHECKING([$LATEX2HTML library directory]) AC_ARG_VAR(LATEX2HTML_LIBDIR, [Directory where LaTeX to HTML translator's additional files reside]) LATEX2HTML_LIBDIR=$($LATEX2HTML -version | sed -n 's/^library directory: \(.*\)/\1/p') if test -z "$LATEX2HTML_LIBDIR"; then AC_MSG_RESULT(none) elif test -d "$LATEX2HTML_LIBDIR"; then AC_MSG_RESULT($LATEX2HTML_LIBDIR) else AC_MSG_RESULT(missing) fi fi AC_PATH_PROG(SPLITHTML, hacha, false) if test "$SPLITHTML" = false; then AC_MSG_WARN(cannot find hacha; will not be able to split HTML documentation on request) fi AC_PATH_PROG(GNUPLOT, gnuplot, false) if test "$GNUPLOT" = false; then AC_MSG_WARN(cannot find gnuplot; will not be able to build documentation) can_build_doc=no missing_for_doc="$missing_for_doc gnuplot" fi AC_PATH_PROG(M4, m4, false) if test "$M4" = false; then AC_MSG_WARN(cannot find m4; will not be able to build documentation) can_build_doc=no missing_for_doc="$missing_for_doc m4" fi AC_PATH_PROG(DOT, dot, false) if test "$DOT" = false; then AC_MSG_WARN(cannot find dot; will not be able to build documentation) can_build_doc=no missing_for_doc="$missing_for_doc dot" fi AC_PATH_PROG(SVGCONVERT, rsvg-convert, false) if test "$SVGCONVERT" = false; then AC_MSG_WARN(cannot find rsvg-convert; will not be able to build documentation) can_build_doc=no missing_for_doc="$missing_for_doc rsvg-convert" fi AC_PATH_PROGS(PS2PDF, [ps2pdf ps2pdf14], false) if test "$PDFLATEX" = false -a "$PS2PDF" != false; then AC_MSG_NOTICE([Alternative PDF generation via ps2pdf available.]) fi AC_PATH_PROGS(DVIPDF, [dvipdfmx dvipdfm dvipdf], false) if test "$PDFLATEX" = false -a "$DVIPDF" != false; then AC_MSG_NOTICE([Alternative PDF generation via dvipdf available.]) fi AM_CONDITIONAL([BUILD_DOC], [test "$can_build_doc" = yes]) if test "$can_build_doc" = no; then no_doc_reason=", because of missing$missing_for_doc" fi AC_ARG_VAR(DYNAMIC_TEX_PREAMBLE, [LaTeX commands to add to top of preamble]) DYNAMIC_TEX_PREAMBLE=\\def\\finishdynamicpreamble{\\relax} AC_MSG_CHECKING(whether to enable debugging) debug_default="no" AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [turn on debugging @<:@default=no@:>@]), [enable_debug=$enableval], [enable_debug=$debug_default]) if test "$enable_debug" = yes; then CXXFLAGS="$CXXFLAGS -g -DDEBUG" AC_MSG_RESULT(yes) enable_debug=yes else CXXFLAGS="$CXXFLAGS -O2 -DNDEBUG" AC_MSG_RESULT(no) enable_debug=no fi AC_MSG_CHECKING(whether to enable image cache) image_cache_default="no" AC_ARG_ENABLE(image_cache, AS_HELP_STRING([--enable-image-cache], [allow for processing of large images @<:@default=no@:>@]), [enable_image_cache=$enableval], [enable_image_cache=$image_cache_default]) if test "$enable_image_cache" = yes; then AC_DEFINE(CACHE_IMAGES, 1, [Define if you want to compile Enblend and Enfuse with image cache]) AC_MSG_RESULT(yes) enable_image_cache=yes else AC_MSG_RESULT(no) enable_image_cache=no fi AC_MSG_CHECKING(whether to compile with OpenMP) openmp_default="no" AC_ARG_ENABLE(openmp, AS_HELP_STRING([--enable-openmp], [compile with OpenMP @<:@default=no@:>@]), [enable_openmp=$enableval], [enable_openmp=$openmp_default]) if test "$enable_openmp" = yes; then AC_MSG_RESULT(yes) AX_OPENMP([enable_openmp=yes]) CFLAGS="$CFLAGS $OPENMP_CFLAGS" CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" fi if test -z "$OPENMP_CXXFLAGS"; then AC_MSG_RESULT(no) enable_openmp=no else if test "$enable_image_cache" = yes; then AC_MSG_WARN([[image cache and OpenMP support are mutually exclusive]]) AC_MSG_WARN([[only configure like this if you want to develop a reentrant image cache]]) warnings=`echo -e "$warnings\n WARNING: Image cache and OpenMP are both enabled! You are a developer, aren't you?"` fi enable_openmp=yes fi AC_CONFIG_FILES([doc/Makefile doc/examples/Makefile doc/examples/enfuse/Makefile doc/examples/enfuse/Makefile.userweight]) AC_CONFIG_FILES([Makefile src/Makefile src/dynamic_loader/Makefile src/layer_selection/Makefile src/win32helpers/Makefile]) AC_OUTPUT AC_MSG_RESULT([ enblend-enfuse now configured for ${host} Source directory: ${srcdir} Installation directory: ${prefix} C++ compiler: ${CXX} CFLAGS: ${CFLAGS:-} CXXFLAGS: ${CXXFLAGS:-} LDFLAGS: ${LDFLAGS:-} LIBS: ${LIBS:-} EXTRA_LIBS (optional): ${EXTRA_LIBS:-} can build all documentation: ${can_build_doc}${no_doc_reason} feature selection: enable debugging support: ${enable_debug} enable malloc debugging: ${enable_dmalloc} enable dynamic loading ${enable_dynload} ${dynload_implementation} OpenEXR image format ${have_exr} use image cache: ${enable_image_cache} use OpenMP: ${enable_openmp} use TCMalloc: ${use_tcmalloc} ${warnings}]) enblend-enfuse-4.2/CMakeModules/0000755000175000017500000000000012676263420013573 500000000000000enblend-enfuse-4.2/CMakeModules/FindJPEG.cmake0000644000175000017500000000260012672731617016045 00000000000000# - Find JPEG for Hugin 0.7 01Nov2007 TKSharpless # Added to support Windows build but should work anywhere. # After looking in UNIX standard places, tries wxWidgets build # tree, which should have this package. # # Call FIND_PACKAGE(wxWidgets REQUIRED) before calling this! # # reads cache variables # wxWidgets_ROOT_DIR # wxWidgets_LIB_DIR # defines cache variables # JPEG_INCLUDE_DIR, where to find headers # JPEG_LIBRARIES, list of release link libraries # JPEG_DEBUG_LIBRARIES, list of debug link libraries # JPEG_FOUND, If != "YES", do not try to use JPEG FIND_PATH(JPEG_INCLUDE_DIR jpeglib.h /usr/local/include /usr/include ${SOURCE_BASE_DIR}/jpeg-9b ${SOURCE_BASE_DIR}/jpeg-9a ${SOURCE_BASE_DIR}/jpeg-9 ${SOURCE_BASE_DIR}/jpeg-8d ${SOURCE_BASE_DIR}/jpeg-7 ) include(FindLibraryForCPU) find_library_for_cpu(JPEG_LIBRARIES WIN32_DEBUG_POSTFIX d NAMES jpeg libjpeg PATHS ${SYSTEM_LIB_DIRS} ${SOURCE_BASE_DIR}/jpeg-9b/x64/Release ${SOURCE_BASE_DIR}/jpeg-9b/Release ${SOURCE_BASE_DIR}/jpeg-9a/lib ${SOURCE_BASE_DIR}/jpeg-9/lib ${SOURCE_BASE_DIR}/jpeg-9/x64/Release ${SOURCE_BASE_DIR}/jpeg-8d/lib ${SOURCE_BASE_DIR}/jpeg-7/lib ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(JPEG DEFAULT_MSG JPEG_INCLUDE_DIR JPEG_LIBRARIES) MARK_AS_ADVANCED(JPEG_INCLUDE_DIR JPEG_LIBRARIES ) enblend-enfuse-4.2/CMakeModules/FindOpenMP.cmake0000644000175000017500000000744612070530376016462 00000000000000# - Finds OpenMP support # This module can be used to detect OpenMP support in a compiler. # If the compiler supports OpenMP, the flags required to compile with # openmp support are set. # # The following variables are set: # OpenMP_C_FLAGS - flags to add to the C compiler for OpenMP support # OpenMP_CXX_FLAGS - flags to add to the CXX compiler for OpenMP support # OPENMP_FOUND - true if openmp is detected # # Supported compilers can be found at http://openmp.org/wp/openmp-compilers/ # Copyright 2008, 2009 Andre.Brodtkorb@ifi.uio.no # # Redistribution AND use is allowed according to the terms of the New # BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. include(CheckCSourceCompiles) include(CheckCXXSourceCompiles) include(FindPackageHandleStandardArgs) set(OpenMP_C_FLAG_CANDIDATES #Gnu "-fopenmp" #Microsoft Visual Studio "/openmp" #Intel windows "-Qopenmp" #Intel "-openmp" #Empty, if compiler automatically accepts openmp " " #Sun "-xopenmp" #HP "+Oopenmp" #IBM XL C/c++ "-qsmp" #Portland Group "-mp" ) set(OpenMP_CXX_FLAG_CANDIDATES ${OpenMP_C_FLAG_CANDIDATES}) # sample openmp source code to test set(OpenMP_C_TEST_SOURCE " #include int main() { #ifdef _OPENMP return 0; #else breaks_on_purpose #endif } ") # use the same source for CXX as C for now set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE}) # if these are set then do not try to find them again, # by avoiding any try_compiles for the flags if(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) set(OpenMP_C_FLAG_CANDIDATES) set(OpenMP_CXX_FLAG_CANDIDATES) endif(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) SET(OpenMP_FLAG_CANDIDATE_COUNTER 0) # check c compiler foreach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") set(CMAKE_REQUIRED_FLAGS "${FLAG}") set(OpenMP_FLAG_DETECTED_${OpenMP_FLAG_CANDIDATE_COUNTER}) check_c_source_compiles("${OpenMP_CXX_TEST_SOURCE}" OpenMP_FLAG_DETECTED_${OpenMP_FLAG_CANDIDATE_COUNTER}) set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") if(OpenMP_FLAG_DETECTED_${OpenMP_FLAG_CANDIDATE_COUNTER}) set(OpenMP_C_FLAGS_INTERNAL "${FLAG}") set(OpenMP_FLAG_DETECTED 1) break() endif(OpenMP_FLAG_DETECTED_${OpenMP_FLAG_CANDIDATE_COUNTER}) math(EXPR OpenMP_FLAG_CANDIDATE_COUNTER "${OpenMP_FLAG_CANDIDATE_COUNTER} + 1") endforeach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) math(EXPR OpenMP_FLAG_CANDIDATE_COUNTER "${OpenMP_FLAG_CANDIDATE_COUNTER} + 1") # check cxx compiler foreach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") set(CMAKE_REQUIRED_FLAGS "${FLAG}") set(OpenMP_FLAG_DETECTED_${OpenMP_FLAG_CANDIDATE_COUNTER}) message(STATUS "Try OpenMP CXX flag = [${FLAG}]") check_cxx_source_compiles("${OpenMP_C_TEST_SOURCE}" OpenMP_FLAG_DETECTED_${OpenMP_FLAG_CANDIDATE_COUNTER}) set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") if(OpenMP_FLAG_DETECTED_${OpenMP_FLAG_CANDIDATE_COUNTER}) set(OpenMP_CXX_FLAGS_INTERNAL "${FLAG}") set(OpenMP_FLAG_DETECTED 1) break() endif(OpenMP_FLAG_DETECTED_${OpenMP_FLAG_CANDIDATE_COUNTER}) math(EXPR OpenMP_FLAG_CANDIDATE_COUNTER "${OpenMP_FLAG_CANDIDATE_COUNTER} + 1") endforeach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) set(OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}" CACHE STRING "C compiler flags for OpenMP parallization") set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS_INTERNAL}" CACHE STRING "C++ compiler flags for OpenMP parallization") # handle the standard arguments for find_package find_package_handle_standard_args(OpenMP DEFAULT_MSG OpenMP_C_FLAGS OpenMP_CXX_FLAGS ) mark_as_advanced( OpenMP_C_FLAGS OpenMP_CXX_FLAGS ) enblend-enfuse-4.2/CMakeModules/FindTCmalloc.cmake0000644000175000017500000000171212376637027017022 00000000000000# - Find TCMALLOC # Find the native TCMALLOC includes and library # # TCMALLOC_INCLUDE_DIR - where to find tcmalloc.h etc. # TCMALLOC_LIBRARIES - List of libraries when using tcmalloc. # TCMALLOC_FOUND - True if tcmalloc found. FIND_PATH(TCMALLOC_INCLUDE_DIR tcmalloc.h PATHS /usr/local/include /usr/include ${CMAKE_SYSTEM_INCLUDE_PATH}/gperftools ${CMAKE_INCLUDE_PATH}/gperftools ${SOURCE_BASE_DIR}/gperftools-2.0/src/windows/gperftools ) find_library(TCMALLOC_LIBRARIES NAMES tcmalloc tcmalloc_minimal libtcmalloc_minimal PATHS ${SYSTEM_LIB_DIRS} ${SOURCE_BASE_DIR}/gperftools-2.0/x64/Release ${SOURCE_BASE_DIR}/gperftools-2.0/Release ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(TCMALLOC DEFAULT_MSG TCMALLOC_INCLUDE_DIR TCMALLOC_LIBRARIES) MARK_AS_ADVANCED( TCMALLOC_LIBRARIES TCMALLOC_INCLUDE_DIR ) enblend-enfuse-4.2/CMakeModules/FindPNG.cmake0000644000175000017500000000236212253101765015737 00000000000000# - Find PNG for Hugin 0.7 01Nov2007 TKSharpless # Added to support Windows build but should work anywhere. # After looking in UNIX standard places, tries wxWidgets build # tree, which should have this package. # # Call FIND_PACKAGE(wxWidgets REQUIRED) before calling this! # # reads cache variables # wxWidgets_ROOT_DIR # wxWidgets_LIB_DIR # defines cache variables # PNG_INCLUDE_DIR, where to find headers # PNG_LIBRARIES, list of release link libraries. # PNG_FOUND, If != "YES", do not try to use PNG. # None of the above will be defined unless ZLIB can be found INCLUDE(FindZLIB) include(FindLibraryWithDebug) SET(PNG_FOUND "NO") IF (ZLIB_FOUND) FIND_PATH(PNG_INCLUDE_DIR png.h /usr/local/include /usr/include ${SOURCE_BASE_DIR}/libpng/include ) find_library_with_debug(PNG_LIBRARIES WIN32_DEBUG_POSTFIX d NAMES png libpng libpng16_static libpng16 libpng15 libpng15_static PATHS ${SYSTEM_LIB_DIRS} ${SOURCE_BASE_DIR}/libpng/lib ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PNG DEFAULT_MSG PNG_INCLUDE_DIR PNG_LIBRARIES) SET(PNG_LIBRARIES ${PNG_LIBRARIES} ${ZLIB_LIBRARIES}) MARK_AS_ADVANCED(PNG_INCLUDE_DIR PNG_LIBRARIES ) ENDIF(ZLIB_FOUND) enblend-enfuse-4.2/CMakeModules/FindVIGRA.cmake0000644000175000017500000000511412311336501016152 00000000000000# - Find VIGRA # Added to support Windows build but should work anywhere. # After looking in UNIX standard places, tries wxWidgets build # tree, which should have this package. # # # reads cache variables # defines cache variables # VIGRA_INCLUDE_DIR, where to find headers # VIGRA_LIBRARIES, list of release link libraries # VIGRA_FOUND, If != "YES", error out as VIGRA is required SET( VIGRA_FOUND "NO" ) IF(WIN32) FIND_PATH(VIGRA_INCLUDE_DIR vigra/gaborfilter.hxx PATHS ${SOURCE_BASE_DIR}/vigra/include ) # for dynamic build, it's vigraimpex.lib and the dll must be copied into hugin's bin folder #SET(VIGRA_LIBRARIES ${SOURCE_BASE_DIR}/vigra/lib/libvigraindex.dll) FIND_LIBRARY_WITH_DEBUG(VIGRA_LIBRARIES WIN32_DEBUG_POSTFIX d NAMES vigraimpex libvigraimpex PATHS ${VIGRA_ROOT_PATH} ${VIGRA_ROOT_PATH}/Release ${VIGRA_ROOT_PATH}/lib ${SOURCE_BASE_DIR}/vigra/lib ) #FIND_FILE(VIGRA_DLL # NAMES vigraimpex.dll # PATHS ${SOURCE_BASE_DIR}/vigra1.6.0/lib #) ELSE(WIN32) FIND_PATH(VIGRA_INCLUDE_DIR vigra/gaborfilter.hxx /usr/local/include /usr/include /opt/local/include ) FIND_LIBRARY(VIGRA_LIBRARIES NAMES vigraimpex libvigraimpex PATHS /usr/lib /usr/local/lib /opt/local/lib ) ENDIF(WIN32) IF (VIGRA_INCLUDE_DIR AND VIGRA_LIBRARIES) SET(VIGRA_FOUND TRUE) ENDIF (VIGRA_INCLUDE_DIR AND VIGRA_LIBRARIES) IF (VIGRA_FOUND) MESSAGE(STATUS "Found VIGRA: ${VIGRA_LIBRARIES}") # we check the version of VIGRA library FIND_FILE(VIGRA_VERSION_FILE VigraConfigVersion.cmake PATH /usr/lib/vigra /usr/local/lib/vigra /opt/local/lib ${SOURCE_BASE_DIR}/vigra/lib/vigra ) IF(${VIGRA_VERSION_FILE} MATCHES "-NOTFOUND") SET(VIGRA_VERSION_CHECK FALSE) # check is done additional in ConfigureChecks.cmake ELSE() # backup of variable PACKAGE_VERSION, it is overwrited in VigraConfigVersion.cmake SET(BACKUP_PACKAGE_VERSION ${PACKAGE_VERSION}) INCLUDE(${VIGRA_VERSION_FILE} NO_POLICY_SCOPE) SET(VIGRA_VERSION ${PACKAGE_VERSION}) SET(PACKAGE_VERSION ${BACKUP_PACKAGE_VERSION}) IF(${VIGRA_VERSION} VERSION_EQUAL 1.9.0 OR ${VIGRA_VERSION} VERSION_GREATER 1.9.0) SET(VIGRA_VERSION_CHECK TRUE) MESSAGE(STATUS "VIGRA version: ${VIGRA_VERSION}") ELSE() MESSAGE(FATAL_ERROR "VIGRA lib is too old.\nEnblend requires at least version 1.9.0, but found version ${VIGRA_VERSION}." ) ENDIF() ENDIF() ELSE (VIGRA_FOUND) MESSAGE(FATAL_ERROR "Could not find VIGRA") ENDIF (VIGRA_FOUND) MARK_AS_ADVANCED( VIGRA_LIBRARIES VIGRA_INCLUDE_DIR ) enblend-enfuse-4.2/CMakeModules/FindLCMS2.cmake0000644000175000017500000000174212650356344016142 00000000000000IF(NOT WIN32) FIND_PATH(LCMS2_INCLUDE_DIR NAMES lcms2.h PATHS /usr/local/include /usr/include ) FIND_LIBRARY(LCMS2_LIBRARIES lcms2 HINTS /usr/local/lib /usr/lib/x86_64-linux-gnu /usr/lib32) ELSE(NOT WIN32) FIND_PATH(LCMS2_ROOT_DIR NAMES include/lcms2.h PATHS /usr/local /usr ${SOURCE_BASE_DIR} PATH_SUFFIXES lcms2-2.7 lcms2-2.6 lcms2-2.5 ) FIND_PATH(LCMS2_INCLUDE_DIR NAMES lcms2.h PATHS ${LCMS2_ROOT_DIR}/include ) include(FindLibraryWithDebug) find_library_with_debug(LCMS2_LIBRARIES WIN32_DEBUG_POSTFIX d NAMES lcms2 lcms2_static PATHS ${LCMS2_ROOT_DIR}/Lib/MS ) MARK_AS_ADVANCED(LCMS2_ROOT_DIR) ENDIF(NOT WIN32) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LCMS2 DEFAULT_MSG LCMS2_INCLUDE_DIR LCMS2_LIBRARIES) MARK_AS_ADVANCED(LCMS2_LIBRARIES LCMS2_INCLUDE_DIR) enblend-enfuse-4.2/CMakeModules/FindZLIB.cmake0000644000175000017500000000212412070530376016050 00000000000000# - Find zlib # Find the native ZLIB includes and library # # ZLIB_INCLUDE_DIR - where to find zlib.h, etc. # ZLIB_LIBRARIES - List of libraries when using zlib. # ZLIB_FOUND - True if zlib found. # - Find TIFF for Hugin 0.7 01Nov2007 TKSharpless # Added to support Windows build but should work anywhere. # After looking in UNIX standard places, tries wxWidgets build # tree, which should have this package. # # reads cache variables # wxWidgets_ROOT_DIR # wxWidgets_LIB_DIR # IF (ZLIB_INCLUDE_DIR) # Already in cache, be silent SET(ZLIB_FIND_QUIETLY TRUE) ENDIF (ZLIB_INCLUDE_DIR) FIND_PATH(ZLIB_INCLUDE_DIR zlib.h /usr/local/include /usr/include ${SOURCE_BASE_DIR}/zlib/include ) include(FindLibraryWithDebug) find_library_with_debug(ZLIB_LIBRARIES WIN32_DEBUG_POSTFIX d NAMES z zlib zlibstatic PATHS ${SYSTEM_LIB_DIRS} ${SOURCE_BASE_DIR}/zlib/lib ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(ZLIB DEFAULT_MSG ZLIB_INCLUDE_DIR ZLIB_LIBRARIES) MARK_AS_ADVANCED( ZLIB_LIBRARIES ZLIB_INCLUDE_DIR ) enblend-enfuse-4.2/CMakeModules/FindPackageHandleStandardArgs.cmake0000644000175000017500000000455212070530376022264 00000000000000# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME (DEFAULT_MSG|"Custom failure message") VAR1 ... ) # This macro is intended to be used in FindXXX.cmake modules files. # It handles the REQUIRED and QUIET argument to FIND_PACKAGE() and # it also sets the _FOUND variable. # The package is found if all variables listed are TRUE. # Example: # # FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR) # # LibXml2 is considered to be found, if both LIBXML2_LIBRARIES and # LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. # If it is not found and REQUIRED was used, it fails with FATAL_ERROR, # independent whether QUIET was used or not. # If it is found, the location is reported using the VAR1 argument, so # here a message "Found LibXml2: /usr/lib/libxml2.so" will be printed out. # If the second argument is DEFAULT_MSG, the message in the failure case will # be "Could NOT find LibXml2", if you don't like this message you can specify # your own custom failure message there. MACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FAIL_MSG _VAR1 ) IF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") IF (${_NAME}_FIND_REQUIRED) SET(_FAIL_MESSAGE "Could not find REQUIRED package ${_NAME}") ELSE (${_NAME}_FIND_REQUIRED) SET(_FAIL_MESSAGE "Could not find OPTIONAL package ${_NAME}") ENDIF (${_NAME}_FIND_REQUIRED) ELSE("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") SET(_FAIL_MESSAGE "${_FAIL_MSG}") ENDIF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG") STRING(TOUPPER ${_NAME} _NAME_UPPER) SET(${_NAME_UPPER}_FOUND TRUE) IF(NOT ${_VAR1}) SET(${_NAME_UPPER}_FOUND FALSE) ENDIF(NOT ${_VAR1}) FOREACH(_CURRENT_VAR ${ARGN}) IF(NOT ${_CURRENT_VAR}) SET(${_NAME_UPPER}_FOUND FALSE) ENDIF(NOT ${_CURRENT_VAR}) ENDFOREACH(_CURRENT_VAR) IF (${_NAME_UPPER}_FOUND) IF (NOT ${_NAME}_FIND_QUIETLY) MESSAGE(STATUS "Found ${_NAME}: ${${_VAR1}}") ENDIF (NOT ${_NAME}_FIND_QUIETLY) ELSE (${_NAME_UPPER}_FOUND) IF (${_NAME}_FIND_REQUIRED) MESSAGE(FATAL_ERROR "${_FAIL_MESSAGE}") ELSE (${_NAME}_FIND_REQUIRED) IF (NOT ${_NAME}_FIND_QUIETLY) MESSAGE(STATUS "${_FAIL_MESSAGE}") ENDIF (NOT ${_NAME}_FIND_QUIETLY) ENDIF (${_NAME}_FIND_REQUIRED) ENDIF (${_NAME_UPPER}_FOUND) ENDMACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS) enblend-enfuse-4.2/CMakeModules/FindOpenCL.cmake0000644000175000017500000000347312253101765016437 00000000000000# Search for OpenCL header and librariy # # It will set # OPENCL_FOUND - system has OpenCL # OPENCL_INCLUDE_DIR - the OpenCL include directory # OPENCL_LIBRARY - link these to use OpenCL # IF(WIN32) # search for AMD/nVidia/Intel SDK with OpenCL headers and lib SET(CL_INCLUDE_PREFIX "CL") FIND_PATH(OPENCL_INCLUDE_DIR NAMES CL/cl.hpp PATHS $ENV{AMDAPPSDKROOT}/include $ENV{INTELOCLSDKROOT}/include $ENV{NVSDKCOMPUTE_ROOT}/OpenCL/common/inc ) IF(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32 bit libs SET(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} $ENV{AMDAPPSDKROOT}/lib/x86 $ENV{INTELOCLSDKROOT}/lib/x86 $ENV{NVSDKCOMPUTE_ROOT}/OpenCL/common/lib/Win32 ) ELSEIF(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64 bit libs SET(OPENCL_LIB_SEARCH_PATH ${OPENCL_LIB_SEARCH_PATH} $ENV{AMDAPPSDKROOT}/lib/x86_64 $ENV{INTELOCLSDKROOT}/lib/x64 $ENV{NVSDKCOMPUTE_ROOT}/OpenCL/common/lib/x64 ) ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 4) FIND_LIBRARY( OPENCL_LIBRARY NAMES OpenCL PATHS ${OPENCL_LIB_SEARCH_PATH} ) ELSE(WIN32) IF(APPLE) SET(CL_INCLUDE_PREFIX "OpenCL") ELSE() SET(CL_INCLUDE_PREFIX "CL") ENDIF() FIND_PATH(OPENCL_INCLUDE_DIR NAMES ${CL_INCLUDE_PREFIX}/cl.h PATHS /usr/local/include /usr/include "/usr/local/cuda/include" ) FIND_LIBRARY(OPENCL_LIBRARY NAMES OpenCL CL clparser PATHS /usr/local/lib /usr/lib ) ENDIF(WIN32) INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenCL DEFAULT_MSG OPENCL_LIBRARY OPENCL_INCLUDE_DIR) IF(OPENCL_FOUND) STRING(TOUPPER ${CL_INCLUDE_PREFIX} _INC_PREFIX) SET(HAVE_${_INC_PREFIX}_CL_HPP 1) ENDIF() MARK_AS_ADVANCED(OPENCL_INCLUDE_DIR OPENCL_LIBRARY) enblend-enfuse-4.2/CMakeModules/HuginMacros.cmake0000644000175000017500000000401712412004405016716 00000000000000# macro to convert a CMAKE list to a string MACRO(LIST2STRING alist astring) FOREACH(elem ${${alist}}) SET(${astring} "${${astring}} ${elem}") ENDFOREACH(elem) ENDMACRO(LIST2STRING) # from http://www.cmake.org/Wiki/CMakeMacroParseArguments MACRO(PARSE_ARGUMENTS prefix arg_names option_names) SET(DEFAULT_ARGS) FOREACH(arg_name ${arg_names}) SET(${prefix}_${arg_name}) ENDFOREACH(arg_name) FOREACH(option ${option_names}) SET(${prefix}_${option} FALSE) ENDFOREACH(option) SET(current_arg_name DEFAULT_ARGS) SET(current_arg_list) FOREACH(arg ${ARGN}) SET(larg_names ${arg_names}) LIST(FIND larg_names "${arg}" is_arg_name) IF (is_arg_name GREATER -1) SET(${prefix}_${current_arg_name} ${current_arg_list}) SET(current_arg_name ${arg}) SET(current_arg_list) ELSE (is_arg_name GREATER -1) SET(loption_names ${option_names}) LIST(FIND loption_names "${arg}" is_option) IF (is_option GREATER -1) SET(${prefix}_${arg} TRUE) ELSE (is_option GREATER -1) SET(current_arg_list ${current_arg_list} ${arg}) ENDIF (is_option GREATER -1) ENDIF (is_arg_name GREATER -1) ENDFOREACH(arg) SET(${prefix}_${current_arg_name} ${current_arg_list}) ENDMACRO(PARSE_ARGUMENTS) include(CheckCXXCompilerFlag) MACRO(set_sse_cxx_flags) IF(CMAKE_COMPILER_IS_GNUCXX) MESSAGE("-- Checking for -march=native support") CHECK_CXX_COMPILER_FLAG("-march=native" MARCHNATIVE) if (MARCHNATIVE) set(MARCH "-march=native") else() MESSAGE("-- Checking for -mtune=native support") CHECK_CXX_COMPILER_FLAG("-mtune=native" MTUNENATIVE) if (MTUNENATIVE) set(MARCH "-mtune=native") else() set(MARCH "-mtune=generic") endif() endif() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -msse2 ${MARCH}") ELSEIF(MSVC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /arch:SSE2") ENDIF(CMAKE_COMPILER_IS_GNUCXX) ENDMACRO(set_sse_cxx_flags) enblend-enfuse-4.2/CMakeModules/FindDlopen.cmake0000644000175000017500000000114712253101765016534 00000000000000# - Find DLOPEN # Find the native DLOPEN includes and library # # DLOPEN_INCLUDE_DIR - where to find dlfcn.h etc. # DLOPEN_LIBRARIES - List of libraries when using dlopen. # DLOPEN_FOUND - True if dlopen found. FIND_PATH(DLOPEN_INCLUDE_DIR dlfcn.h PATHS /usr/local/include /usr/include ) find_library(DLOPEN_LIBRARIES NAMES dlopen dl ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(DLOPEN DEFAULT_MSG DLOPEN_INCLUDE_DIR DLOPEN_LIBRARIES) MARK_AS_ADVANCED( DLOPEN_LIBRARIES DLOPEN_INCLUDE_DIR ) enblend-enfuse-4.2/CMakeModules/FindLibraryForCPU.cmake0000644000175000017500000000256112676263420017745 00000000000000# # FIND_LIBRARY_WITH_CPU # -> enhanced FIND_LIBRARY to allow searching for platform # specific versions of libraries on Win32. This is common # for MSVC based builds that may output a file into a directory # particular for that CPU architecture (traditionally, # "Win32" and "x64" for 32-bit and 64-bit builds) # # # Based in part on FIND_LIBRARY_WITH_DEBUG # Copyright (c) 2009, Ryan Sleevi, # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. MACRO(FIND_LIBRARY_FOR_CPU var_name) IF(NOT MSVC) FIND_LIBRARY(${var_name} ${ARGN}) ELSE(NOT MSVC) SET(args ${ARGN}) SET(names "") SET(newpaths "") SET(found_paths 0) IF(CMAKE_CL_64) SET(msvc_platform "x64") ELSE(CMAKE_CL_64) SET(msvc_platform "Win32") ENDIF(CMAKE_CL_64) FOREACH(val ${args}) IF(found_paths) # Prefer the CPU-specific path over the generic/original path LIST(APPEND newpaths "${val}/${msvc_platform}") LIST(APPEND newpaths "${val}") ELSE(found_paths) IF(${val} STREQUAL "PATHS") SET(found_paths 1) ELSE() LIST(APPEND names "${val}") ENDIF() ENDIF(found_paths) ENDFOREACH(val) FIND_LIBRARY(${var_name} ${names} PATHS ${newpaths}) ENDIF(NOT MSVC) ENDMACRO(FIND_LIBRARY_FOR_CPU) enblend-enfuse-4.2/CMakeModules/FindCXX11Compiler.cmake0000644000175000017500000000505712253372456017625 00000000000000# Check if compiler supports C++11 features # and which compiler switches are necessary # CXX11_FLAG : contains the necessary compiler flag # # Copyright (c) 2013 Thomas Modes # # This file is part of Enblend. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. The name of the author may not be used to endorse or promote products # derived from this software without specific prior written permission. # # This file 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 Enblend; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # INCLUDE(CheckCXXSourceCompiles) INCLUDE(FindPackageHandleStandardArgs) SET(CXX11_FLAG_CANDIDATES "--std=gnu++11" "--std=c++11" "--std=gnu++0x" ) # sample openmp source code to test SET(CXX11_TEST_SOURCE " template struct check { static_assert(sizeof(int) <= sizeof(T), \"not big enough\"); }; typedef check> right_angle_brackets; class TestDeleted { public: TestDeleted() = delete; }; int a; decltype(a) b; typedef check check_type; check_type c; check_type&& cr = static_cast(c); auto d = a; int main() { return 0; }; ") # check c compiler FOREACH(FLAG ${CXX11_FLAG_CANDIDATES}) SET(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") SET(CMAKE_REQUIRED_FLAGS "${FLAG}") UNSET(CXX11_FLAG_DETECTED CACHE) CHECK_CXX_SOURCE_COMPILES("${CXX11_TEST_SOURCE}" CXX11_FLAG_DETECTED) SET(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") IF(CXX11_FLAG_DETECTED) SET(CXX11_FLAG "${FLAG}") BREAK() ENDIF() ENDFOREACH() # handle the standard arguments for find_package FIND_PACKAGE_HANDLE_STANDARD_ARGS(CXX11Compiler DEFAULT_MSG CXX11_FLAG) MARK_AS_ADVANCED(CXX11_FLAG) enblend-enfuse-4.2/CMakeModules/FindGSL.cmake0000644000175000017500000001146712633234555015754 00000000000000# Script copied from http://www.cmake.org/pipermail/cmake/attachments/20080709/38127d1f/attachment.obj # and modified for use in enblend # (replaced calls like: # SET(GSL_LIBRARIES "`${GSL_CONFIG} --libs`") # with: # EXEC_PROGRAM(${GSL_CONFIG} ARGS "--libs" OUTPUT_VARIABLE GSL_LIBRARIES) # ) ################### # Script found on KDE-edu list # TODO replace this with OpenCog SIAI copyrighted version. # # Look for the header file # Try to find gnu scientific library GSL # See # http://www.gnu.org/software/gsl/ and # http://gnuwin32.sourceforge.net/packages/gsl.htm # # Once run this will define: # # GSL_FOUND = system has GSL lib # # GSL_LIBRARIES = full path to the libraries # on Unix/Linux with additional linker flags from "gsl-config --libs" # # CMAKE_GSL_CXX_FLAGS = Unix compiler flags for GSL, essentially "`gsl-config --cxxflags`" # # GSL_INCLUDE_DIR = where to find headers # # GSL_LINK_DIRECTORIES = link directories, useful for rpath on Unix # GSL_EXE_LINKER_FLAGS = rpath on Unix # # Felix Woelk 07/2004 # Jan Woetzel # # www.mip.informatik.uni-kiel.de # -------------------------------- IF(WIN32) SET(GSL_POSSIBLE_ROOT_DIRS ${SOURCE_BASE_DIR}/gsl ${SOURCE_BASE_DIR}/gsl-1.17 ${SOURCE_BASE_DIR}/gsl-1.16 ${SOURCE_BASE_DIR}/gsl-1.15 ) FIND_PATH(GSL_INCLUDE_DIR NAMES gsl/gsl_cdf.h gsl/gsl_randist.h PATHS ${GSL_POSSIBLE_ROOT_DIRS} PATH_SUFFIXES include DOC "GSL header include dir" ) include(FindLibraryWithDebug) find_library_with_debug(GSL_GSL_LIBRARY WIN32_DEBUG_POSTFIX d NAMES gsl libgsl PATHS ${GSL_POSSIBLE_ROOT_DIRS} PATH_SUFFIXES lib DOC "GSL library dir" ) find_library_with_debug(GSL_GSLCBLAS_LIBRARY WIN32_DEBUG_POSTFIX d NAMES gslcblas libgslcblas cblas PATHS ${GSL_POSSIBLE_ROOT_DIRS} PATH_SUFFIXES lib DOC "GSL cblas library dir" ) SET(GSL_LIBRARIES ${GSL_GSL_LIBRARY} ${GSL_GSLCBLAS_LIBRARY}) #MESSAGE("DBG\n" # "GSL_GSL_LIBRARY=${GSL_GSL_LIBRARY}\n" # "GSL_GSLCBLAS_LIBRARY=${GSL_GSLCBLAS_LIBRARY}\n" # "GSL_LIBRARIES=${GSL_LIBRARIES}") INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(GSL DEFAULT_MSG GSL_INCLUDE_DIR GSL_GSL_LIBRARY GSL_GSLCBLAS_LIBRARY) ELSE(WIN32) IF(UNIX) SET(GSL_CONFIG_PREFER_PATH "$ENV{GSL_DIR}/bin" "$ENV{GSL_DIR}" "$ENV{GSL_HOME}/bin" "$ENV{GSL_HOME}" CACHE STRING "preferred path to GSL (gsl-config)") FIND_PROGRAM(GSL_CONFIG gsl-config ${GSL_CONFIG_PREFER_PATH} /usr/bin/ ) # MESSAGE("DBG GSL_CONFIG ${GSL_CONFIG}") IF (GSL_CONFIG) # set CXXFLAGS to be fed into CXX_FLAGS by the user: EXEC_PROGRAM(${GSL_CONFIG} ARGS "--cflags" OUTPUT_VARIABLE GSL_CXX_FLAGS) # set INCLUDE_DIRS to prefix+include EXEC_PROGRAM(${GSL_CONFIG} ARGS "--prefix" OUTPUT_VARIABLE GSL_PREFIX) SET(GSL_INCLUDE_DIR ${GSL_PREFIX}/include CACHE STRING INTERNAL) # set link libraries and link flags EXEC_PROGRAM(${GSL_CONFIG} ARGS "--libs" OUTPUT_VARIABLE GSL_LIBRARIES) # extract link dirs for rpath EXEC_PROGRAM(${GSL_CONFIG} ARGS "--libs" OUTPUT_VARIABLE GSL_CONFIG_LIBS ) # split off the link dirs (for rpath) # use regular expression to match wildcard equivalent "-L*" # with is a space or a semicolon STRING(REGEX MATCHALL "[-][L]([^ ;])+" GSL_LINK_DIRECTORIES_WITH_PREFIX "${GSL_CONFIG_LIBS}" ) # MESSAGE("DBG GSL_LINK_DIRECTORIES_WITH_PREFIX=${GSL_LINK_DIRECTORIES_WITH_PREFIX}") # remove prefix -L because we need the pure directory for LINK_DIRECTORIES IF (GSL_LINK_DIRECTORIES_WITH_PREFIX) STRING(REGEX REPLACE "[-][L]" "" GSL_LINK_DIRECTORIES ${GSL_LINK_DIRECTORIES_WITH_PREFIX} ) ENDIF (GSL_LINK_DIRECTORIES_WITH_PREFIX) SET(GSL_EXE_LINKER_FLAGS "-Wl,-rpath,${GSL_LINK_DIRECTORIES}" CACHE STRING INTERNAL) # MESSAGE("DBG GSL_LINK_DIRECTORIES=${GSL_LINK_DIRECTORIES}") # MESSAGE("DBG GSL_EXE_LINKER_FLAGS=${GSL_EXE_LINKER_FLAGS}") # ADD_DEFINITIONS("-DHAVE_GSL") # SET(GSL_DEFINITIONS "-DHAVE_GSL") MARK_AS_ADVANCED( GSL_CXX_FLAGS GSL_INCLUDE_DIR GSL_LIBRARIES GSL_LINK_DIRECTORIES GSL_DEFINITIONS ) MESSAGE(STATUS "Using GSL from ${GSL_PREFIX}") ELSE(GSL_CONFIG) MESSAGE("FindGSL.cmake: gsl-config not found. Please set it manually. GSL_CONFIG=${GSL_CONFIG}") ENDIF(GSL_CONFIG) INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(GSL DEFAULT_MSG GSL_CONFIG) ENDIF(UNIX) ENDIF(WIN32) IF(GSL_LIBRARIES) IF(GSL_INCLUDE_DIR OR GSL_CXX_FLAGS) SET(GSL_FOUND 1) ENDIF(GSL_INCLUDE_DIR OR GSL_CXX_FLAGS) ENDIF(GSL_LIBRARIES) enblend-enfuse-4.2/CMakeModules/FindOpenEXR.cmake0000644000175000017500000000722012631033506016566 00000000000000# Try to find the OpenEXR libraries # This check defines: # # OPENEXR_FOUND - system has OpenEXR # OPENEXR_INCLUDE_DIR - OpenEXR include directory # OPENEXR_LIBRARIES - Libraries needed to use OpenEXR # # Copyright (c) 2006, Alexander Neundorf, # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. if (OPENEXR_INCLUDE_DIR AND OPENEXR_LIBRARIES) # in cache already SET(OPENEXR_FOUND TRUE) else (OPENEXR_INCLUDE_DIR AND OPENEXR_LIBRARIES) IF (NOT WIN32 OR MINGW) # use pkg-config to get the directories and then use these values # in the FIND_PATH() and FIND_LIBRARY() calls INCLUDE(UsePkgConfig) PKGCONFIG(OpenEXR _OpenEXRIncDir _OpenEXRLinkDir _OpenEXRLinkFlags _OpenEXRCflags) ENDIF (NOT WIN32 OR MINGW) FIND_PATH(OPENEXR_INCLUDE_DIR ImfRgbaFile.h ${_OpenEXRIncDir} ${_OpenEXRIncDir}/OpenEXR/ /usr/include /usr/local/include ${SOURCE_BASE_DIR}/Deploy/include ${SOURCE_BASE_DIR}/Deploy/include/OpenEXR ) include(FindLibraryWithDebug) find_library_with_debug(OPENEXR_HALF_LIBRARY WIN32_DEBUG_POSTFIX d NAMES Half PATHS ${_OPENEXRLinkDir} ${SYSTEM_LIB_DIRS} ${SOURCE_BASE_DIR}/Deploy/lib/ ${SOURCE_BASE_DIR}/Deploy/lib/Release ) find_library_with_debug(OPENEXR_IEX_LIBRARY WIN32_DEBUG_POSTFIX d NAMES Iex-2_2 Iex PATHS ${_OPENEXRLinkDir} ${SYSTEM_LIB_DIRS} ${SOURCE_BASE_DIR}/Deploy/lib/ ${SOURCE_BASE_DIR}/Deploy/lib/Release ) find_library_with_debug(OPENEXR_ILMTHREAD_LIBRARY WIN32_DEBUG_POSTFIX d NAMES IlmThread-2_2 IlmThread PATHS ${_OPENEXRLinkDir} ${SYSTEM_LIB_DIRS} ${SOURCE_BASE_DIR}/Deploy/lib/ ${SOURCE_BASE_DIR}/Deploy/lib/Release ) find_library_with_debug(OPENEXR_IMATH_LIBRARY WIN32_DEBUG_POSTFIX d NAMES Imath-2_2 Imath PATHS ${_OPENEXRLinkDir} ${SYSTEM_LIB_DIRS} ${SOURCE_BASE_DIR}/Deploy/lib/ ${SOURCE_BASE_DIR}/Deploy/lib/Release ) find_library_with_debug(OPENEXR_ILMIMF_LIBRARY WIN32_DEBUG_POSTFIX d NAMES IlmImf-2_2 IlmImf PATHS ${_OPENEXRLinkDir} ${SYSTEM_LIB_DIRS} ${SOURCE_BASE_DIR}/Deploy/lib/ ${SOURCE_BASE_DIR}/Deploy/lib/Release ) if (OPENEXR_INCLUDE_DIR AND OPENEXR_IMATH_LIBRARY AND OPENEXR_ILMIMF_LIBRARY AND OPENEXR_IEX_LIBRARY AND OPENEXR_HALF_LIBRARY) set(OPENEXR_FOUND TRUE) if (OPENEXR_ILMTHREAD_LIBRARY) set(OPENEXR_LIBRARIES ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_ILMIMF_LIBRARY} ${OPENEXR_IEX_LIBRARY} ${OPENEXR_HALF_LIBRARY} ${OPENEXR_ILMTHREAD_LIBRARY} CACHE STRING "The libraries needed to use OpenEXR") else (OPENEXR_ILMTHREAD_LIBRARY) set(OPENEXR_LIBRARIES ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_ILMIMF_LIBRARY} ${OPENEXR_IEX_LIBRARY} ${OPENEXR_HALF_LIBRARY} CACHE STRING "The libraries needed to use OpenEXR") endif (OPENEXR_ILMTHREAD_LIBRARY) endif (OPENEXR_INCLUDE_DIR AND OPENEXR_IMATH_LIBRARY AND OPENEXR_ILMIMF_LIBRARY AND OPENEXR_IEX_LIBRARY AND OPENEXR_HALF_LIBRARY) if (OPENEXR_FOUND) if (NOT OpenEXR_FIND_QUIETLY) message(STATUS "Found OPENEXR: ${OPENEXR_LIBRARIES}") endif (NOT OpenEXR_FIND_QUIETLY) else (OPENEXR_FOUND) if (OpenEXR_FIND_REQUIRED) message(FATAL_ERROR "Could NOT find OPENEXR") endif (OpenEXR_FIND_REQUIRED) endif (OPENEXR_FOUND) MARK_AS_ADVANCED( OPENEXR_INCLUDE_DIR OPENEXR_LIBRARIES OPENEXR_ILMIMF_LIBRARY OPENEXR_IMATH_LIBRARY OPENEXR_IEX_LIBRARY OPENEXR_HALF_LIBRARY OPENEXR_ILMTHREAD_LIBRARY ) endif (OPENEXR_INCLUDE_DIR AND OPENEXR_LIBRARIES) enblend-enfuse-4.2/CMakeModules/FindLibraryWithDebug.cmake0000644000175000017500000000755412070530376020533 00000000000000# # FIND_LIBRARY_WITH_DEBUG # -> enhanced FIND_LIBRARY to allow the search for an # optional debug library with a WIN32_DEBUG_POSTFIX similar # to CMAKE_DEBUG_POSTFIX when creating a shared lib # it has to be the second and third argument # Copyright (c) 2007, Christian Ehrlicher, # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. MACRO(FIND_LIBRARY_WITH_DEBUG var_name) IF(NOT WIN32) FIND_LIBRARY(${var_name} ${ARGN}) ELSE(NOT WIN32) PARSE_ARGUMENTS(FIND_LIB_WITH_DEBUG "WIN32_DEBUG_POSTFIX;WIN32_DEBUG_PATH_SUFFIX;WIN32_RELEASE_PATH_SUFFIX;NAMES;PATHS" "" ${ARGN}) IF(NOT FIND_LIB_WITH_DEBUG_NAMES) LIST(GET FIND_LIB_WITH_DEBUG_DEFAULT_ARGS 0 FIND_LIB_WITH_DEBUG_NAMES) LIST(REMOVE_AT FIND_LIB_WITH_DEBUG_DEFAULT_ARGS 0) ENDIF(NOT FIND_LIB_WITH_DEBUG_NAMES) IF(NOT FIND_LIB_WITH_DEBUG_PATHS) LIST(GET FIND_LIB_WITH_DEBUG_DEFAULT_ARGS 0 FIND_LIB_WITH_DEBUG_PATHS) ENDIF(NOT FIND_LIB_WITH_DEBUG_PATHS) IF(NOT FIND_LIB_WITH_DEBUG_WIN32_DEBUG_POSTFIX AND NOT FIND_LIB_WITH_DEBUG_WIN32_DEBUG_PATH_SUFFIX AND NOT FIND_LIB_WITH_DEBUG_WIN32_RELEASE_PATH_SUFFIX) FIND_LIBRARY(${var_name} NAMES ${FIND_LIB_WITH_DEBUG_NAMES} PATHS ${FIND_LIB_WITH_DEBUG_PATHS}) ELSE(NOT FIND_LIB_WITH_DEBUG_WIN32_DEBUG_POSTFIX AND NOT FIND_LIB_WITH_DEBUG_WIN32_DEBUG_PATH_SUFFIX AND NOT FIND_LIB_WITH_DEBUG_WIN32_RELEASE_PATH_SUFFIX) SET(libpaths_release "") SET(libpaths_debug "") SET(libnames_release "") SET(libnames_debug "") FOREACH(libpath ${FIND_LIB_WITH_DEBUG_PATHS}) FOREACH(rel_suffix ${FIND_LIB_WITH_DEBUG_WIN32_RELEASE_PATH_SUFFIX}) LIST(APPEND libpaths_release "${libpath}/${rel_suffix}") ENDFOREACH(rel_suffix ${FIND_LIB_WITH_DEBUG_WIN32_RELEASE_PATH_SUFFIX}) IF(NOT DEFINED ${FIND_LIB_WITH_DEBUG_WIN32_RELEASE_PATH_SUFFIX}) LIST(APPEND libpaths_release "${libpath}") ENDIF(NOT DEFINED ${FIND_LIB_WITH_DEBUG_WIN32_RELEASE_PATH_SUFFIX}) FOREACH(deb_suffix ${FIND_LIB_WITH_DEBUG_WIN32_DEBUG_PATH_SUFFIX}) LIST(APPEND libpaths_debug "${libpath}/${deb_suffix}") ENDFOREACH(deb_suffix ${FIND_LIB_WITH_DEBUG_WIN32_DEBUG_PATH_SUFFIX}) IF(NOT DEFINED ${FIND_LIB_WITH_DEBUG_WIN32_DEBUG_PATH_SUFFIX}) LIST(APPEND libpaths_debug "${libpath}") ENDIF(NOT DEFINED ${FIND_LIB_WITH_DEBUG_WIN32_DEBUG_PATH_SUFFIX}) ENDFOREACH(libpath ${FIND_LIB_WITH_DEBUG_PATHS}) FOREACH(libname ${FIND_LIB_WITH_DEBUG_NAMES}) LIST(APPEND libnames_release "${libname}") LIST(APPEND libnames_debug "${libname}${FIND_LIB_WITH_DEBUG_WIN32_DEBUG_POSTFIX}") ENDFOREACH(libname ${FIND_LIB_WITH_DEBUG_NAMES}) # search the release lib find_library_for_cpu(${var_name}_RELEASE NAMES ${libnames_release} PATHS ${libpaths_release} ) # search the debug lib find_library_for_cpu(${var_name}_DEBUG NAMES ${libnames_debug} PATHS ${libpaths_debug} ) IF(${var_name}_RELEASE AND ${var_name}_DEBUG) # both libs found SET(${var_name} optimized ${${var_name}_RELEASE} debug ${${var_name}_DEBUG}) ELSE(${var_name}_RELEASE AND ${var_name}_DEBUG) IF(${var_name}_RELEASE) # only release found SET(${var_name} ${${var_name}_RELEASE}) ELSE(${var_name}_RELEASE) # only debug (or nothing) found SET(${var_name} ${${var_name}_DEBUG}) ENDIF(${var_name}_RELEASE) ENDIF(${var_name}_RELEASE AND ${var_name}_DEBUG) MARK_AS_ADVANCED(${var_name}_RELEASE) MARK_AS_ADVANCED(${var_name}_DEBUG) ENDIF(NOT FIND_LIB_WITH_DEBUG_WIN32_DEBUG_POSTFIX AND NOT FIND_LIB_WITH_DEBUG_WIN32_DEBUG_PATH_SUFFIX AND NOT FIND_LIB_WITH_DEBUG_WIN32_RELEASE_PATH_SUFFIX) ENDIF(NOT WIN32) ENDMACRO(FIND_LIBRARY_WITH_DEBUG) enblend-enfuse-4.2/CMakeModules/FindTIFF.cmake0000644000175000017500000000261012672731617016051 00000000000000# - Find TIFF for Hugin 0.7 01Nov2007 TKSharpless # Added to support Windows build but should work anywhere. # After looking in UNIX standard places, tries wxWidgets build # tree, which should have this package. # # Call FIND_PACKAGE(wxWidgets REQUIRED) before calling this! # # reads cache variables # wxWidgets_ROOT_DIR # wxWidgets_LIB_DIR # defines cache variables # TIFF_INCLUDE_DIR, where to find headers # TIFF_LIBRARIES, list of link libraries for release # TIFF_DEBUG_LIBRARIES ditto for debug # TIFF_FOUND, If != "YES", do not try to use TIFF. FIND_PATH(TIFF_INCLUDE_DIR tiff.h /usr/local/include /usr/include ${SOURCE_BASE_DIR}/tiff/include ${SOURCE_BASE_DIR}/tiff-4.0.3/libtiff ${SOURCE_BASE_DIR}/tiff-4.0.0beta5/libtiff ${SOURCE_BASE_DIR}/tiff-3.9.2/libtiff ${SOURCE_BASE_DIR}/tiff-3.8.2/libtiff ) include(FindLibraryWithDebug) find_library_with_debug(TIFF_LIBRARIES WIN32_DEBUG_POSTFIX d NAMES tiff libtiff PATHS ${SYSTEM_LIB_DIRS} ${SOURCE_BASE_DIR}/tiff/lib ${SOURCE_BASE_DIR}/tiff-4.0.3/libtiff ${SOURCE_BASE_DIR}/tiff-4.0.0beta5/libtiff ${SOURCE_BASE_DIR}/tiff-3.9.2/libtiff ${SOURCE_BASE_DIR}/tiff-3.8.2/libtiff ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(TIFF DEFAULT_MSG TIFF_INCLUDE_DIR TIFF_LIBRARIES) MARK_AS_ADVANCED(TIFF_INCLUDE_DIR TIFF_LIBRARIES) enblend-enfuse-4.2/config.guess0000755000175000017500000012355012404676534013533 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2014 Free Software Foundation, Inc. timestamp='2014-03-23' # This file 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. # # 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, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches with a ChangeLog entry to config-patches@gnu.org. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: enblend-enfuse-4.2/install-sh0000755000175000017500000003325512423346767013224 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: enblend-enfuse-4.2/config.sub0000755000175000017500000010577512404676534013207 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2014 Free Software Foundation, Inc. timestamp='2014-09-11' # This file 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. # # 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, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: enblend-enfuse-4.2/ConfigureChecks.cmake0000644000175000017500000001354512632610262015246 00000000000000# This file is part of enblend. # Licence details can be found in the file COPYING. # # Copyright (c) 2009-2015, Kornel Benko # , Ryan Sleevi # , Harry van der Wolf # include(CheckIncludeFile) include(CheckIncludeFileCXX) include(CheckIncludeFiles) include(CheckSymbolExists) include(CheckFunctionExists) include(CheckLibraryExists) include(CheckTypeSize) include(CheckCXXSourceCompiles) include(CheckFunctionExists) include(TestBigEndian) MACRO(AddHeaderTestToConfig header var) STRING(CONFIGURE "/* Define if you have the <${header}> header file. */\n#cmakedefine ${var} 1\n" _str) SET(CMAKE_HEADER_EXISTS "${CMAKE_HEADER_EXISTS}${_str}\n") UNSET(_str) ENDMACRO() MACRO(AddFunctionTestToConfig function var) STRING(CONFIGURE "/* Define if you have the '${function}' function. */\n#cmakedefine ${var} 1\n" _str) SET(CMAKE_FUNCTION_EXISTS "${CMAKE_FUNCTION_EXISTS}${_str}\n") UNSET(_str) ENDMACRO() #Check for some include files and set appropriate variables # e.g. "sys/dir.h" found => "HAVE_SYS_DIR_H" set to 1 foreach(_fl "dirent.h" "fenv.h" "inttypes.h" "limits.h" "memory.h" "stdint.h" "stdlib.h" "stdbool.h" "strings.h" "string.h" "sys/stat.h" "sys/types.h" "unistd.h" "windows.h" "sys/times.h") string(REGEX REPLACE "[/\\.]" "_" _var ${_fl}) string(TOUPPER "${_var}" _FLN) check_include_file_cxx("${_fl}" "HAVE_${_FLN}" ) AddHeaderTestToConfig("${_fl}" "HAVE_${_FLN}") endforeach() #Check for functions set(CMAKE_REQUIRED_LIBRARIES -lm) foreach(_fc atexit fesetround floor fseeko lrint lrintf memset mkstemp pow select sqrt malloc strchr strcspn strdup strerror strerror_r strpbrk strrchr strtol strtok_r strerror_r strtoul) string(TOUPPER "${_fc}" _FC) check_function_exists(${_fc} "HAVE_${_FC}") AddFunctionTestToConfig("${_fc}" "HAVE_${_FC}") endforeach() if(HAVE_DIRENT_H) check_cxx_source_compiles( " #include DIR *DI; int i = closedir(DI); int main(){return(0);} " CLOSEDIR_INT) endif(HAVE_DIRENT_H) if (NOT CLOSEDIR_INT) set(CLOSEDIR_VOID 1) endif() CHECK_LIBRARY_EXISTS(rt clock_gettime "time.h" HAVE_CLOCK_GETTIME) AddFunctionTestToConfig("clock_gettime" "HAVE_CLOCK_GETTIME") # Check for restrict keyword # Builds the macro A_C_RESTRICT form automake set(RESTRICT) foreach(ac_kw __restrict __restrict__ _Restrict restrict) check_cxx_source_compiles( " int foo (int * ${ac_kw} ip) { return ip[0]; } int main(){ int s[1]; int * ${ac_kw} t = s; t[0] = 0; return foo(t); } " RESTRICT_${ac_kw}_FOUND) if(RESTRICT_${ac_kw}_FOUND) set(RESTRICT ${ac_kw}) break() endif() endforeach() if(VIGRA_FOUND AND NOT VIGRA_VERSION_CHECK) unset(VIGRA_SETIMAGEINDEX CACHE) set(CMAKE_REQUIRED_INCLUDES ${VIGRA_INCLUDE_DIR}) set(CMAKE_REQUIRED_LIBRARIES ${VIGRA_LIBRARIES}) check_cxx_source_compiles( " #include #include vigra::ImageImportInfo info(\"image.tif\"); int main(){ vigra::BRGBImage image; vigra::BImage alpha; vigra::impexListFormats(); info.setImageIndex(99); vigra::importImageAlpha(info, destImage(image), destImage(alpha)); return(0); } " VIGRA_SETIMAGEINDEX) if(NOT VIGRA_SETIMAGEINDEX) message(FATAL_ERROR "Vigra library too old") endif() endif() message(STATUS "CMAKE_ERRFILE = ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log") message(STATUS "CMAKE_LOGFILE = ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log") check_type_size( ptrdiff_t HAVE_PTRDIFF_T ) # How to check if stdbool.h conforms to C99? check_cxx_source_compiles( " #include DIR *a = 0; int main(){return(0);} " HAVE_SYS_DIR_H) AddHeaderTestToConfig("sys/dir.h" "HAVE_SYS_DIR_H") check_cxx_source_compiles( " #include DIR *a = 0; int main(){return(0);} " HAVE_NDIR_H) AddHeaderTestToConfig("ndir.h" "HAVE_NDIR_H") check_cxx_source_compiles( " #include DIR *a = 0; int main(){return(0);} " HAVE_SYS_NDIR_H) AddHeaderTestToConfig("sys/ndir.h" "HAVE_SYS_NDIR_H") check_include_files("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS) check_cxx_source_compiles( " #include static void sg(int b) { return;} int main(int c, char *av[]) { signal(0, sg); return(0);} " RETSIGTYPE_VOID) if(RETSIGTYPE_VOID) set(RETSIGTYPE void) else(RETSIGTYPE_VOID) set(RETSIGTYPE int) endif(RETSIGTYPE_VOID) test_big_endian(WORDS_BIGENDIAN) check_cxx_source_compiles( " #include off_t a = 0; int main(){return(0);} " HAVE_OFF_T) check_cxx_source_compiles( " #include size_t a = 0; int main(){return(0);} " HAVE_SIZE_T) check_cxx_source_compiles( " #include int main(){char b;char *a = strerror_r(0, &b, 0); return(0);} " STRERROR_R_CHAR_P) SET(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") SET(CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS}") check_cxx_source_compiles( " #include #include #include int main() { std::string s(\"foo\"); const std::string& const_s = std::as_const(s); return 0; } " HAVE_AS_CONST ) check_cxx_source_compiles( " #include #include int main() { std::tr2::sys::path filepath; std::string s=filepath.filename().string(); return 0; }; " HAVE_STD_FILESYSTEM ) SET(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") # workaround for older boost versions (<1.55) set(CMAKE_REQUIRED_INCLUDES ${Boost_INCLUDE_DIR}) check_cxx_source_compiles( " #include #ifndef BOOST_FALLTHROUGH #error \"BOOST_FALLTHROUGH not defined\" #endif int main(){return(0);} " HAVE_BOOST_FALLTHROUGH ) enblend-enfuse-4.2/missing0000755000175000017500000001533012423346767012611 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2013 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # 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, 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, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: enblend-enfuse-4.2/ar-lib0000755000175000017500000001330212423346767012303 00000000000000#! /bin/sh # Wrapper for Microsoft lib.exe me=ar-lib scriptversion=2012-03-01.08; # UTC # Copyright (C) 2010-2013 Free Software Foundation, Inc. # Written by Peter Rosin . # # 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, 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, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # func_error message func_error () { echo "$me: $1" 1>&2 exit 1 } file_conv= # func_file_conv build_file # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv in mingw) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin) file=`cygpath -m "$file" || echo "$file"` ;; wine) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_at_file at_file operation archive # Iterate over all members in AT_FILE performing OPERATION on ARCHIVE # for each of them. # When interpreting the content of the @FILE, do NOT use func_file_conv, # since the user would need to supply preconverted file names to # binutils ar, at least for MinGW. func_at_file () { operation=$2 archive=$3 at_file_contents=`cat "$1"` eval set x "$at_file_contents" shift for member do $AR -NOLOGO $operation:"$member" "$archive" || exit $? done } case $1 in '') func_error "no command. Try '$0 --help' for more information." ;; -h | --h*) cat <&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ $(srcdir)/config.h.in AUTHORS COPYING ChangeLog NEWS README \ ar-lib compile config.guess config.sub depcomp install-sh \ missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/_ac_latex_test.m4 \ $(top_srcdir)/m4/ac_latex_class.m4 \ $(top_srcdir)/m4/ac_latex_package.m4 \ $(top_srcdir)/m4/ac_prog_ar.m4 \ $(top_srcdir)/m4/ac_prog_latex.m4 \ $(top_srcdir)/m4/ac_type_sig_atomic_t.m4 \ $(top_srcdir)/m4/ax_boost_base.m4 \ $(top_srcdir)/m4/ax_cxx_as_const.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ $(top_srcdir)/m4/ax_openmp.m4 \ $(top_srcdir)/m4/ax_prog_perl_modules.m4 \ $(top_srcdir)/m4/ax_with_prog.m4 $(top_srcdir)/m4/lrint.m4 \ $(top_srcdir)/m4/lrintf.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CONVERT = @CONVERT@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_IMPLEMENTATION = @DL_IMPLEMENTATION@ DOT = @DOT@ DVIPDF = @DVIPDF@ DVIPS = @DVIPS@ DYNAMIC_TEX_PREAMBLE = @DYNAMIC_TEX_PREAMBLE@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTRA_LIBS = @EXTRA_LIBS@ GNUPLOT = @GNUPLOT@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_INLINE = @HAVE_INLINE@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LATEX = @LATEX@ LATEX2HTML = @LATEX2HTML@ LATEX2HTML_LIBDIR = @LATEX2HTML_LIBDIR@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ M4 = @M4@ MAKEINDEX = @MAKEINDEX@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ OPENEXR_CFLAGS = @OPENEXR_CFLAGS@ OPENEXR_LIBS = @OPENEXR_LIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PDFLATEX = @PDFLATEX@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ PS2PDF = @PS2PDF@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SPLITHTML = @SPLITHTML@ STRIP = @STRIP@ SVGCONVERT = @SVGCONVERT@ TEXLOGANALYSER = @TEXLOGANALYSER@ VERSION = @VERSION@ VIGRAIMPEX_LIB = @VIGRAIMPEX_LIB@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ amsmath = @amsmath@ bindir = @bindir@ bold_extra = @bold_extra@ boretti_classesansparametre = @boretti_classesansparametre@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ color = @color@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enumitem = @enumitem@ exec_prefix = @exec_prefix@ float = @float@ footnote = @footnote@ graphicx = @graphicx@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hyperref = @hyperref@ hyphenat = @hyphenat@ ifpdf = @ifpdf@ includedir = @includedir@ index = @index@ infodir = @infodir@ install_sh = @install_sh@ latex = @latex@ latexsym = @latexsym@ libdir = @libdir@ libexecdir = @libexecdir@ listings = @listings@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ microtype = @microtype@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ ragged2e = @ragged2e@ refrep = @refrep@ report = @report@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ shorttoc = @shorttoc@ srcdir = @srcdir@ suffix = @suffix@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ url = @url@ xstring = @xstring@ EXTRA_DIST = \ README.txt VERSION \ CMakeLists.txt CMakeModules ConfigureChecks.cmake config.h.cmake @BUILD_DOC_TRUE@MAYBE_DOC = doc SUBDIRS = src $(MAYBE_DOC) DIST_SUBDIRS = src doc ACLOCAL_AMFLAGS = -I m4 all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ distcheck distclean distclean-generic distclean-hdr \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: enblend-enfuse-4.2/VERSION0000644000175000017500000000000412676432415012246 000000000000004.2 enblend-enfuse-4.2/config.h.in0000644000175000017500000001715112676242414013232 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Define if Boost is not recent enough to define BOOST_FALLTHROUGH itself */ #undef BOOST_FALLTHROUGH /* Define if you want to compile Enblend and Enfuse with image cache */ #undef CACHE_IMAGES /* Define to 1 if the `closedir' function returns void instead of `int'. */ #undef CLOSEDIR_VOID /* Define to enable malloc debugger library */ #undef DMALLOC /* Define to enable malloc debugger function checking */ #undef DMALLOC_FUNC_CHECK /* Use gmodule-2.0 dl implementation */ #undef GMODULE_DL /* define if the compiler supports as_const() */ #undef HAVE_AS_CONST /* Define to 1 if you have the `atexit' function. */ #undef HAVE_ATEXIT /* define if the Boost library is available */ #undef HAVE_BOOST /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* define if the compiler supports basic C++11 syntax */ #undef HAVE_CXX11 /* Define to 1 if you have the declaration of `strerror_r', and to 0 if you don't. */ #undef HAVE_DECL_STRERROR_R /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_DIRENT_H /* Define if you have support for dynamic loading */ #undef HAVE_DL /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #undef HAVE_FENV_H /* Define to 1 if you have the `fesetround' function. */ #undef HAVE_FESETROUND /* Define to 1 if you have the `floor' function. */ #undef HAVE_FLOOR /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ #undef HAVE_FSEEKO /* Define to 1 if you have the header file. */ #undef HAVE_GMODULE_H /* Define to 1 if you have the header file. */ #undef HAVE_GPERFTOOLS_TCMALLOC_H /* Define if functions can be declared `inline'. */ #undef HAVE_INLINE /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `gsl' library (-lgsl). */ #undef HAVE_LIBGSL /* Define to 1 if you have the `gslcblas' library (-lgslcblas). */ #undef HAVE_LIBGSLCBLAS /* Define to 1 if you have the `lcms2' library (-llcms2). */ #undef HAVE_LIBLCMS2 /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define if you have C99's lrint function. */ #undef HAVE_LRINT /* Define if you have C99's lrintf function. */ #undef HAVE_LRINTF /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if you have the `mkstemp' function. */ #undef HAVE_MKSTEMP /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_NDIR_H /* Define to 1 if you have the `pow' function. */ #undef HAVE_POW /* Define to 1 if the system has the type `ptrdiff_t'. */ #undef HAVE_PTRDIFF_T /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the `sqrt' function. */ #undef HAVE_SQRT /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `strcspn' function. */ #undef HAVE_STRCSPN /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the `strerror_r' function. */ #undef HAVE_STRERROR_R /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strpbrk' function. */ #undef HAVE_STRPBRK /* Define to 1 if you have the `strrchr' function. */ #undef HAVE_STRRCHR /* Define to 1 if you have the `strtok_r' function. */ #undef HAVE_STRTOK_R /* Define to 1 if you have the `strtol' function. */ #undef HAVE_STRTOL /* Define to 1 if you have the `strtoul' function. */ #undef HAVE_STRTOUL /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define if exists. */ #undef HAVE_SYS_TIMES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define if you have Google's TCMalloc library */ #undef HAVE_TCMALLOC /* Define to 1 if you have the header file. */ #undef HAVE_TCMALLOC_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Define if you have EXR library */ #undef HasEXR /* Define if you have the jpeg library */ #undef HasJPEG /* Define if you have the png library */ #undef HasPNG /* Define if you have the tiff library */ #undef HasTIFF /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Use POSIX dl implementation */ #undef POSIX_DL /* Map RESTRICT onto C99 restrict keyword */ #undef RESTRICT /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if strerror_r returns char *. */ #undef STRERROR_R_CHAR_P /* Version number of package */ #undef VERSION /* Define if using the dmalloc debugging malloc package */ #undef WITH_DMALLOC /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ #undef _LARGEFILE_SOURCE /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `long int' if does not define. */ #undef off_t /* Define to the equivalent of the C99 'restrict' keyword, or to nothing if this is not supported. Do not define if restrict is supported directly. */ #undef restrict /* Work around a bug in Sun C++: it does not support _Restrict or __restrict__, even though the corresponding Sun C compiler ends up with "#define restrict _Restrict" or "#define restrict __restrict__" in the previous line. Perhaps some future version of Sun C++ will work with restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ #if defined __SUNPRO_CC && !defined __RESTRICT # define _Restrict # define __restrict__ #endif /* largest atomically accessible type */ #undef sig_atomic_t /* Define to `unsigned int' if does not define. */ #undef size_t enblend-enfuse-4.2/README.txt0000644000175000017500000004664012676176342012720 00000000000000Copyright (C) 2004-2009 Andrew Mihal. Copyright (C) 2009-2016 Christoph Spiel. This file is part of Enblend. * Programs This packages contains the programs Enblend and Enfuse. The source code and further information about Enblend are available at: http://enblend.sf.net ** Enblend Enblend is a tool for compositing images using a Burt&Adelson multiresolution spline. This technique tries to make the seams between the input images invisible. The basic idea is that image features should be blended across a transition zone proportional in size to the spatial frequency of the features. For example, objects like trees and windowpanes have rapid changes in color. By blending these features in a narrow zone, you will not be able to see the seam because the eye already expects to see color changes at the edge of these features. Clouds and sky are the opposite. These features have to be blended across a wide transition zone because any sudden change in color will be immediately noticeable. Enblend expects each input file to have an alpha channel. The alpha channel should indicate the region of the file that has valid image data. Enblend compares the alpha regions in the input files to find the areas where images overlap. Alpha channels can be used to indicate to Enblend that certain portions of an input image should not contribute to the final image. Enblend does not align images for you. Use a tool like Hugin or PanoTools to do this. The files produced by these programs are exactly what Enblend is designed to work with. ** Enfuse Enfuse is a tool for automatic exposure blending, contrast blending and much more. It can be used to fuse an exposure bracketed step automatically into a nicely looking image. * Installation GNU Make is required to build the project, because some of the Makefiles contain pattern rules. ** Tarball ./configure YOUR-OPTIONS-IF-ANY-GO-HERE make make install ** Mercurial Repository *** AutoConf/AutoMake In the root directory of the project issue: make --makefile=Makefile.scm ./configure YOUR-OPTIONS-IF-ANY-GO-HERE make make install The package fully supports VPATH builds. Thus the following command sequence builds in a separate directory. cd ROOT-DIRECTORY make --makefile=Makefile.scm mkdir BUILD-DIR cd BUILD-DIR ROOT-DIRECTORY/configure YOUR-OPTIONS-IF-ANY-GO-HERE make make install If a less verbose output of the Make-process is desired, pass `--enable-silent-rules' to configure(1), or `V=0' to make(1). As out build uses recursion make(1) reports "Entering directory" and "Leaving directory" which can only be suppressed with passing option `--no-print-directory' to make(1). *** CMake The canonical way to build Enblend and Enfuse is with Autotools, this is, autoconf(1) and automake(1). An alternative CMake build has been added since version 4.0. The CMake build strives to replicate the Autotools build. It may or may not work for you. It is currently maintained but not supported, meaning that it could break anywhere anytime in the future. cmake . make make install Analogously to Autotools, CMake allows for VPATH builds: mkdir BUILD-DIR cd BUILD-DIR cmake ROOT-DIRECTORY make make install * Specific Configuration Options Among the usual configuration options of the GNU autoconf system, the configure(1) script offers the following options to tailor Enblend and Enfuse. Remember that configure(1) creates a file called "config.h" that can serve for fine-tuning the configuration. We write the default values of all configuration options in capital letters. ** --enable-on-demand-dynlink=CHECK/yes/no Link Enblend and Enfuse binaries with flags that instruct the dynamic linker to delay loading dynamic libraries until they are actually needed. This feature slightly decreases the load-time of the binaries. ** --enable-openmp=yes/NO -DENABLE_OPENMP=ON/off (CMake) Parallelize parts of Enblend and Enfuse with OpenMP. See http://www.openmp.org/ If auto-detection of OpenMP misfires, set appropriate OPENMP_CXXFLAGS during configuration. For example, CLang++ may need the argument-form of option `-fopenmp': -fopenmp=libiomp5 In addition OpenMP support libraries may live in non-standard places. These too can be specified in OPENMP_CXXFLAGS, because the flags will be used for compilation and linking. When OpenMP support has been enabled, the utilization of special features of the actual, underlying OpenMP implementation can be controlled as usual with the environment variables OMP_NUM_THREADS, OMP_NESTED and OMP_DYNAMIC. See the OpenMP specification for details on the usage of these variables. ** --enable-debug=yes/NO Compile without optimizations and enable all debug-checking code. The default is "no", build an optimized version without debugging symbols. ** --with-dl=CHECK/yes/no/dl/gmodule Enable user-defined exposure weight functions in Enblend. With argument "check", test for POSIX-compatible dynamic-loader (dl) and if unsuccessful for GLib implementation (gmodule). ** --with-tcmalloc=CHECK/yes/no -DENABLE_TCMALLOC=OFF/on (CMake) Compile with Google's TCMalloc. This library generally improves memory allocation performance. Enblend and Enfuse prefer TCMalloc's functions inside OpenMP parallel regions and thereby reduce the load of the operating system's memory allocator. Find more information on TCMalloc at http://goog-perftools.sourceforge.net/doc/tcmalloc.html ** --with-dmalloc=yes/NO Compile with the debug-malloc library. The library is available at http://www.dmalloc.com/. ** --with-openexr=CHECK/yes/no Build with support for reading and writing OpenEXR images. See http://www.openexr.com/ for the required libraries. * CMake Specifics ** Configuration Options These options only apply to CMake. *** -DCPACK_BINARY_:BOOL=OFF/on Create a package for the specified , where is "DEB", "RPM", or "NSIS". *** -DCPACK_BINARY_:BOOL=ON/off Create other packages for the specified , where is "TBZ2", "TGZ", "STGZ", or "TZ". *** -DPACK_SOURCE_:BOOL=OFF/on Create a source package for the specified , where is "TBZ2", "TGZ", "TZ", or "ZIP". ** Configuration Example Creating a RedHat package on OpenSuSE cmake . \ -DDOC=ON \ -DENABLE_OPENMP=ON \ -DCPACK_BINARY_RPM:BOOL=ON make package This will create a package enblend-4.0.595-Linux.rpm, which you may install with sudo rpm -U enblend-4.0.595-Linux.rpm ** Important Configured Make(1) Targets help List all available targets. edit_cache If cmake-gui(1) is installed, start the GUI to edit the "CMakeCache.txt" file. enblend Create an Enblend executable. enfuse Create an Enfuse executable. man Create the manual pages for Enblend and Enfuse. install Install everything in the proper places. package Create package(s) specified with the CPACK_BINARY_:BOOL parameter of CMake. It is preferred to create a package and use the package manager to install it rather than using the "install" target. rebuild_cache In a changed environment (e.g. newly installed packages) this is the way to discard cached values, so that CMake again starts searching for everything. package_source Build a source package like autotools "make dist". * Extra Make(1) Variables ** Compilation You can override Makefile variables the usual way. In addition the build process supplies several variables, all starting with "EXTRA", that add their value to the "usual suspects". These are CPPFLAGS -- EXTRACPPFLAGS CFLAGS -- EXTRACFLAGS CXXFLAGS -- EXTRACXXFLAGS LDFLAGS -- EXTRALDFLAGS All these "EXTRA" are intentionally unaffected by the Automake/Autoconf generation of the Makefiles proper. That way developers can override configured settings in any make(1) run or quickly build the project with new combinations of flags. For example, to quickly add an additional define, use make EXTRACPPFLAGS=-DDEBUG_8BIT_ONLY To compile for coverage analysis, say make EXTRACXXFLAGS="-O0 --coverage" EXTRALDFLAGS="--coverage" analogously for profiling analysis make EXTRACXXFLAGS=-pg EXTRALDFLAGS=-pg ** Documentation Generation We have introduced the variable DYNAMIC_TEX_PREAMBLE to give the maintainers and packagers better control over the generation of the documentation. The contents of the variable goes _before_ `\documentclass' so that even the document class can be selected dynamically. DYNAMIC_TEX_PREAMBLE can define the argument-less macros `\documentclassoptions' which defines LaTeX \documentclass options (thingies within square brackets) and `\finishdynamicpreamble' which is expanded right before `\begin{document}' and thus _after_ all packages have been loaded. Some possibilities for `DYNAMIC_TEX_PREAMBLE' are \hyperreftrue \referencemanualtrue \usepackage[showframe]{geometry} \def\documentclassoptions{11pt,twoside} \def\finishdynamicpreamble{\overfullrule=2pt\relax} * Documentation The distribution includes the manual pages in src/enblend.1 src/enfuse.1 After the configuration you can build documentation in PostScript, HTML, and possibly PDF formats. make ps make pdf make html The default paper size for all non-HTML formats is DIN A4. Override make(1) variable `PAPERSIZE' to get e.g. Letter format. The default resolution is 600 dpi; override it with `PRINT_RESOLUTION'. The _printed_ versions can be formatted in two different styles: the usual LaTeX `report' and `refman' style that borrows from old reference manuals. Pass DYNAMIC_TEX_PREAMBLE=\referencemanualtrue to make(1) when generating a non-HTML format to get the `refman' style. The reference manual style does _not_ work with HTML, in other words, hevea(1) will barf. By default only PDFLaTeX turns on HyperRef, for all other translators (in particular if PDF is indirectly generated) it must be enabled with DYNAMIC_TEX_PREAMBLE=\hyperreftrue ** HTML Generation The default target `html' builds the HTML documentation as monolithic files, which means the single HTML file "enblend.html" for Enblend and "enfuse.html" for Enfuse. To build split versions with one chapter per file of each of them use the target `split-html', where the root files will be `enblend-index.html' and `enfuse-index.html' . Install the broken-down version with `install-split-html'. ** PDF Generation The canonical way to reach at PDF files i.e. make pdf is directly, via PDFLaTeX: LaTeX -> PDF. If for some reason this path does not work, we provide two alternatives. *** Alternative 1: LaTeX -> DVI -> PDF Use dvipdfmx(1) to convert the final DVI files to PDF. It is recommended to issue a make clean before starting to construct the PDF files this way! Add the following commands to DYNAMIC_TEX_PREAMBLE: - To get correctly positioned graphics \PassOptionsToPackage{dvipdfmx}{graphicx} - For all the hyperref goodies (e.g. clickable cross refferences) \PassOptionsToPackage{dvipdfmx}{hyperref}\hyperreftrue - To get the right color associations \PassOptionsToPackage{dvipdfmx}{color} Sometimes EXTRA_LATEX_FLAGS='-shell-escape' may be required. The targets are called "enblend.dvi.pdf" and "enfuse.dvi.pdf", rename the products if necessary. See doc/Makefile.am for details. *** Alternative 2: LaTeX -> DVI -> PostScript -> PDF Use GhostScript (gs(1)) in the incarnation of ps2pdf(1) to convert the final PostScript files to PDF. None of the hyperref goodies makes it through dvips(1). The targets are called "enblend.ps.pdf" and "enfuse.ps.pdf"; rename if necessary; see doc/Makefile.am for details. ** Required Tools For Building the Documentation Note that some additional packages are required to build these formats: convert - ImageMagick's swiss army knife of graphics format conversion found at http://www.imagemagick.org/. dvips - Convert TeX's DVI format to PostScript. gnuplot - Render plots (.gp) in text, PNG, EPS, and PDF formats. Check out http://www.gnuplot.info/. hevea - Convert LaTeX to HTML. Find more information at http://hevea.inria.fr/. latex, pdflatex - Typeset the LaTeX documents in DVI or PDF. makeindex - Index generation for several typesetters. dot - Graph generation. Part of the `GraphViz' suite. See http://www.graphviz.org/. rsvg-convert - Convert SVG to a variety of other formats, not only raster images, but also EPS. Check out http://librsvg.sourceforge.net/. The tool texloganalyser(1) is optional. Its sole use is to beautify LaTeX output in non-verbose (V=0) mode. * Operating System Specific Instructions and Hints ** GNU/Linux *** High-Performance Binaries To configure and compile high-performance versions of Enblend and Enfuse configure SMP boxes with --enable-openmp and pass EXTRACXXFLAGS="-march=native -O2" to make(1). The resulting binaries are pretty fast, although other configuration options or compiler flags might improve their performance even more. *** Xmi and Xi To avoid direct linkage to the two X11 libraries Xmi and Xi add "--without-x" to the parameters of configure(1). ** MacOSX *** Compiling on MacOSX On MacOSX you can build Enblend/Enfuse with Fink and with MacPorts. This README only describes the MacPorts way. **** Prerequisites - XCode: Install the XCode version for your MacOSX version. Download it from http://developer.apple.com/tools/download/ - MacPorts: Install MacPorts for your MacOSX version. Download it from http://www.macports.org/ **** Provide necessary dependencies From the command line: $ sudo port install make lcms boost jpeg tiff libpng OpenEXR mercurial Note that Enblend/Enfuse can be build via AutoConf/AutoMake and via CMake. The latter is experimental. If you want to build via CMake, add "cmake" to the previous command line after "mercurial" like this: $ sudo port install make lcms boost jpeg tiff libpng OpenEXR mercurial cmake **** Compile As MacPorts resides in /opt/local, which is not a standard library/binary/include path for most source packages, you need to specify that during the configure step. Via AutoConf/AutoMake: cd enblend make --makefile=Makefile.scm mkdir build cd build CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib ../configure make sudo make install Via CMake: cd enblend make --makefile=Makefile.scm mkdir build cd build CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib cmake .. make sudo make install This will install Enblend/Enfuse in /usr/local. **** Other compilation options Please also check the AutoConf/AutoMake and CMake variables for more build options. ** Win *** General There are two different archives: one with 32-bit executables, the other one with 64-bit executables. Both variants are compiled with multi-threaded support (via OpenMP). *** Compiling on Windows **** Prerequisites You will need to following tools for compiling: - MS Visual C++ 2015, works also with Community Edition (older compiler may work, but have not been tested) - CMake, at least version 2.8 - Perl, e.g. ActiveState Perl CMake expects all sources and libraries in one folder. So, create a folder, e.g., "d:\src", extract Enblend/Enfuse into this folder, and also put all libraries into this folder. You need the following libraries for reading and writing different image formats. We state the version and the folder name of the libraries used as of March 2016 in square brackets. - libtiff [libtiff-4.0.6 in tiff] - zlib, required by libtiff [1.2.8 in zlib] - libjpeg (optional) [jpeg-9b] - libpng (optional) [libpng-1.6.21 in libpng] - OpenEXR and IlmBase (optional), compiled libraries are expected in folder "Deploy" [OpenEXR-2.2.0 and IlmBase-2.2.0] - vigra, required, should be compiled against same libtifff, libjpeg, libpng and OpenEXR as used for Enblend/Enfuse [1.10.0 in vigra] Enblend/Enfuse also depend on the following libraries: - Boost [1.60 in boost_1_60_0] - Only header files are used by default. - Optionally, Enblend/Enfuse can use the Filesystem Library. However, this library needs to compiled against STLport. - Little-CMS2 [2.4 in lcm2-2.4] **** Compile 1. Start cmake-gui or cmake-setup. 2. Enter path to Enblend/Enfuse source in "Where is the source code". 3. Enter path where to build the executable, e.g. "d:\src\build-enblend". In following, it will be denoted as . 4. Select "Configure" when asked for a generator select the appropriate generator. 5. Activate the appropriate options. ***** ENABLE_OPENMP=on/OFF Parallelize parts of Enblend and Enfuse with OpenMP. See http://www.openmp.org/ If OpenMP support has been enabled, the utilization of special features of the actual, underlying OpenMP implementation can be controlled as usual with the environment variables OMP_NUM_THREADS, OMP_NESTED and OMP_DYNAMIC. See the OpenMP specification for details on the usage of these variables. ***** ENABLE_SSE2=on/OFF Creates executable which make use of the advanced features (SSE2) of modern processors. ***** DOC=on/OFF Building the documentation works also on Windows. It requires more tools (see above). Some tools have several different variants for Windows available, but not all work with Enblend/Enfuse documentation. If you experience errors try another variant or version. **** Compile (cont.) 6. Select "Configure". Maybe you need start the configuration step several times until all dependencies are resolved. 7. Select "Generate". 8. Close CMake. 9. Open solution file \enblend.sln. 10. Select "Release" in Solution Configuration pull-down menu, and then choose Build > Build Solution. This step takes some time. 11. Select project "INSTALL" in Solution Explorer, and then choose Build > Project Only > Build Only INSTALL. 12. Close Visual C++ 2008 Express Edition 13. Find the generated executables in \INSTALLDIR\FILES. * License Enblend 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. Enblend 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 Enblend; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Local Variables: mode: outline End: enblend-enfuse-4.2/AUTHORS0000644000175000017500000000101412542456651012250 00000000000000Enblend/Enfuse developers: Pablo d'Angelo Mikołaj Leszczyński Max Lyons Andrew Mihal Thomas Modes Christoph Spiel Brent Townshend Win32 porting: Joe Beda Mark - mjz Ryan Sleevi CMake maintanance: Kornel Benko enblend-enfuse-4.2/ChangeLog0000644000175000017500000000000212070530376012737 00000000000000. enblend-enfuse-4.2/COPYING0000644000175000017500000004325412070530376012240 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.