# Maintainer (arch): Antonio Rojas <arojas@archlinux.org>
# Contributor: Ray Rashif <schiv@archlinux.org>
# Contributor: Tobias Powalowski <tpowa@archlinux.org>
# Contributor: André Silva <emulatorman@hyperbola.info>
# Contributor: Márcio Silva <coadde@hyperbola.info>
# Maintainer: Omar Vega Ramos <ovruni@gnu.org.pe>
# Contributor: grizzlyuser <grizzlyuser@protonmail.com>
# Contributor: bill-auger <bill-auger@programmer.net>


# parabola changes and rationale:
# - remove support for non-free/patent-encumbered algorithms and graphics
#   (SIFT and SURF algorithms, "lena" images, CUDA)
# - disable build of non-free intel 'ippicv/ippiw'
# - include extra sources which would be downloaded at build-time
#   the 'gapi' module would not be built without 'ade'
#   configure stage:
#     -- IPPICV: Downloading ippicv_2020_lnx_intel64_20191018_general.tgz from ...
#     -- ADE: Downloading v0.1.2a.zip from ...
#     "Couldn't download files from the Internet."
#     --     Unavailable:                 gapi python2 ts
#   build stage:
#     /build/opencv/src/opencv-4.7.0/samples/cpp/tutorial_code/gapi/doc_snippets/dynamic_graph_snippets.cpp:1:10:
#       fatal error: opencv2/gapi.hpp: No such file or directory
#       1 | #include <opencv2/gapi.hpp>


# NOTE: This PKGBUILD is kept in-sync, as closely as possible,
#       with arch{,arm,32}, for the sake of documentation and cleaner diffs.
#       That also helps to identify which changes were made by Parabola vs upstream.
#       Therefore, this PKGBUILD may declare blacklisted dependencies, non-free sources,
#       or include code for anti-features; but those will be filtered-out subsequently.
#       Any code which implements an anti-feature should be commented-out;
#       and include an 'anti-feature' comment, for clarity.
#       Any blacklisted dependencies and non-free sources should be filtered,
#       and include a 'non-free' comment, for clarity.
#       Without those over-rides, the resulting program may not be FSDG-fit.
#       Do not circumvent those over-rides, if compiling for the Parabola repos.


pkgbase=opencv
pkgname=(opencv opencv-samples python-opencv opencv-cuda)
pkgname=( ${pkgname[*]/opencv-cuda/} ) # non-free
pkgver=4.7.0
pkgrel=12
_pkgver_i686=4.6.0
_pkgrel_i686=6.0
eval "[[ -v _pkgver_${CARCH} ]] && pkgver=\$_pkgver_${CARCH}" # our different arches do not
eval "[[ -v _pkgrel_${CARCH} ]] && pkgrel=\$_pkgrel_${CARCH}" # always roll at the same speed
pkgrel+=.parabola1
pkgdesc='Open Source Computer Vision Library'
pkgdesc="${pkgdesc/Open Source/}"
arch=(x86_64)
arch+=(armv7h i686)
license=(BSD3)
url='https://opencv.org/'
depends=(tbb openexr gst-plugins-base libdc1394 cblas lapack libgphoto2 openjpeg2 ffmpeg protobuf)
makedepends=(cmake python-numpy python-setuptools mesa eigen hdf5 lapacke qt6-5compat vtk glew ant java-environment
             pugixml openmpi cudnn fmt nlohmann-json)
makedepends=( ${makedepends[*]/cudnn/} ) # non-free
makedepends+=( openblas ) # undefined reference to `cblas_{c,d,s,z}gemm'
optdepends=('opencv-samples: samples'
            'vtk: for the viz module'
            'glew: for the viz module'
            'qt6-base: for the HighGUI module'
            'hdf5: for the HDF5 module'
            'opencl-icd-loader: For coding with OpenCL'
            'java-runtime: Java interface')
source=(https://github.com/opencv/opencv/archive/$pkgver/$pkgname-$pkgver.tar.gz
        https://github.com/opencv/opencv_contrib/archive/$pkgver/opencv_contrib-$pkgver.tar.gz
        https://github.com/opencv/opencv/commit/82616eec.patch
        vtk9.patch)

mksource=( ${source[*]} )
source=(https://repo.parabola.nu/other/${pkgname}-libre/${pkgname}-libre-${pkgver}.tar.gz{,.sig})
sha256sums=('8df0079cdbe179748a18d44731af62a245a45ebf5085223dc03133954c662973'
            '42df840cf9055e59d0e22c249cfb19f04743e1bdad113d31b1573d3934d62584'
            'a71e8ffad606d518a846296a06e59beac38887b30021a72b08321aeffd43a75d'
            'f35a2d4ea0d6212c7798659e59eda2cb0b5bc858360f7ce9c696c77d3029668e')
_sums_i686=('8df0079cdbe179748a18d44731af62a245a45ebf5085223dc03133954c662973'  # upstream source-ball
            '42df840cf9055e59d0e22c249cfb19f04743e1bdad113d31b1573d3934d62584') # contrib source-ball
eval "[[ -v _sums_${CARCH} ]] && sha256sums=( \${_sums_${CARCH}[*]} ${sha256sums[*]:2} )"

mksha256sums=( ${sha256sums[*]} )
sha256sums=('00ee9f3fa2428366cefa1d29f717136abfad38d46f2f748508a599db7e57894e'
            SKIP)
validpgpkeys=('3954A7AB837D0EA9CFA9798925DB7D9B5A8D4B40') # bill-auger


# TODO: move these sources above (they should be mksources)
# _ippicv_rev=a56b6ac6f030c312b2dce17430eef13aed9af274
_ade_ver=0.1.2a
source+=( # https://raw.githubusercontent.com/opencv/opencv_3rdparty/${_ippicv_rev}/ippicv/ippicv_2020_lnx_intel64_20191018_general.tgz  # see note in mksource()
         ade-${_ade_ver}.zip::https://github.com/opencv/ade/archive/v${_ade_ver}.zip                                                ) # see note in mksource()
sha256sums+=( # '08627fa5660d52d59309a572dd7db5b9c8aea234cfa5aee0942a1dd903554246'
             '4e32d16c56c2ecc0d8f4fc48cb9eb4af2be2048e7c71b430aa073b03bb8e1e48')


mksource() {
  ## opencv ##

  cd "${srcdir}"/${pkgname}-${pkgver}

  # remove lena.png and lena.jpg images
  rm -v $(find . -iname '*lena*')


  ## opencv_contrib ##

  cd "${srcdir}"/opencv_contrib-${pkgver}

  # remove SIFT and SURF algorithms
  rm -rv modules/xfeatures2d

  # remove CUDA modules
  rm -rv modules/cuda*


  ## upstream prepare() ##

  cd "${srcdir}"/

# prepare() {
  patch -d $pkgname-$pkgver -p1 < vtk9.patch # Don't require all vtk optdepends
  [[ "${CARCH}" == i686 ]] || # n/a 4.6.0
  patch -d $pkgname-$pkgver -p1 < 82616eec.patch # https://github.com/opencv/opencv/issues/23323
}

prepare() { # TODO: move all of prepare() into mksource()
  ## disable build of non-free modules ##

  cd "${srcdir}"/${pkgname}-${pkgver}

  # NOTE: because a bogus define: 'IPPROOT' is passed to cmake in build(),
  #       this 'download_ippicv()' LOC should not be hit - but, delete it anyways
  rm -rf 3rdparty/ippicv/
  grep 'download_ippicv(ICV_PACKAGE_ROOT)'    cmake/OpenCVFindIPP.cmake &> /dev/null &&
  sed -i 's|download_ippicv([^)]*)|return()|' cmake/OpenCVFindIPP.cmake              &&
  ! grep 'download_ippicv(ICV_PACKAGE_ROOT)'  cmake/OpenCVFindIPP.cmake &> /dev/null ||
  ! echo "download_ippicv (non-free) - mksource needs reworking"                     || exit 1


  ## prepare extra sources ##
return 0
  cd "${srcdir}"/${pkgname}-${pkgver}

  local sed_rx="s|if(ade_DIR)|OCV_OPTION(ade_DIR \"use local \'ade\' build\" \"${srcdir}/build-ade/\")\n&|"
  grep 'if(ade_DIR)' modules/gapi/cmake/init.cmake         &> /dev/null &&
  sed -i "${sed_rx}" modules/gapi/cmake/init.cmake                      &&
  grep "OCV_OPTION(ade_DIR " modules/gapi/cmake/init.cmake &> /dev/null ||
  ! echo "ade_DIR (FTBS offline) - mksource needs reworking"            || exit 1

# WIP: 'ade' compiles; but opencv can not find or use it
#      after compiling 'ade', ${srcdir}/build-ade/ is the location of adeConfig.cmake
# build log:
#  |  CMake Warning at modules/gapi/cmake/init.cmake:14 (find_package):
#  |    By not providing "Findade.cmake" in CMAKE_MODULE_PATH this project has
#  |    asked CMake to find a package configuration file provided by "ade", but
#  |    CMake did not find one.
#  |
#  |    Could not find a package configuration file provided by "ade" (requested
#  |    version 0.1.0) with any of the following names:
#  |
#  |      adeConfig.cmake
#  |      ade-config.cmake
#  |
#  |    Add the installation prefix of "ade" to CMAKE_PREFIX_PATH or set "ade_DIR"
#  |    to a directory containing one of the above files.  If "ade" provides a
#  |    separate development package or SDK, be sure it has been installed.
#  |  Call Stack (most recent call first):
#  |    cmake/OpenCVModule.cmake:298 (include)
#  |    cmake/OpenCVModule.cmake:361 (_add_modules_1)
#  |    cmake/OpenCVModule.cmake:385 (ocv_glob_modules)
#  |    CMakeLists.txt:951 (ocv_register_modules)
# parabola_options+=" -Dade_DIR=\"${srcdir}/build-ade/\"" # prepare extra sources
# parabola_options+=" -DCMAKE_PREFIX_PATH=\"${srcdir}/build-ade/\"" # prepare extra sources
# WIP: Neither of the preceding build options satisfies the CMake Warning above.
#      The `sed` command above eliminates the above error; but it still tries to download 'ade'.
#      That o/c fails and the 'gapi' module still is not built.
}

build() {
  # SSE{2,3} is not available for armv7h or i686 (ARM has 'NEON' instead)
  local parabola_options=''
  case "$CARCH" in
    armv7h|i686) parabola_options='-DCPU_BASELINE_DISABLE=SSE,SSE2'                         ;;
    x86_64     ) parabola_options='-DCPU_BASELINE_DISABLE=SSE3 -DCPU_BASELINE_REQUIRE=SSE2' ;;
  esac
  parabola_options+=' -DIPPROOT=/this-is-non-free' # disable build of non-free modules
parabola_options+=" -Dade_DIR=\"${srcdir}/build-ade/\"" # prepare extra sources

  export JAVA_HOME="/usr/lib/jvm/default"
  # cmake's FindLAPACK doesn't add cblas to LAPACK_LIBRARIES, so we need to specify them manually
  _opts="-DWITH_OPENCL=ON \
         -DWITH_OPENGL=ON \
         -DOpenGL_GL_PREFERENCE=LEGACY \
         -DWITH_TBB=ON \
         -DWITH_VULKAN=ON \
         -DWITH_QT=ON \
         -DBUILD_TESTS=OFF \
         -DBUILD_PERF_TESTS=OFF \
         -DBUILD_EXAMPLES=ON \
         -DBUILD_PROTOBUF=OFF \
         -DPROTOBUF_UPDATE_FILES=ON \
         -DINSTALL_C_EXAMPLES=ON \
         -DINSTALL_PYTHON_EXAMPLES=ON \
         -DCMAKE_INSTALL_PREFIX=/usr \
         -DCPU_BASELINE_DISABLE=SSE3 \
         -DCPU_BASELINE_REQUIRE=SSE2 \
         -DOPENCV_EXTRA_MODULES_PATH=$srcdir/opencv_contrib-$pkgver/modules \
         -DOPENCV_SKIP_PYTHON_LOADER=ON \
         -DLAPACK_LIBRARIES=/usr/lib/liblapack.so;/usr/lib/libblas.so;/usr/lib/libcblas.so \
         -DLAPACK_CBLAS_H=/usr/include/cblas.h \
         -DLAPACK_LAPACKE_H=/usr/include/lapacke.h \
         -DOPENCV_GENERATE_PKGCONFIG=ON \
         -DOPENCV_ENABLE_NONFREE=ON \
         -DOPENCV_JNI_INSTALL_PATH=lib \
         -DOPENCV_GENERATE_SETUPVARS=OFF \
         -DEIGEN_INCLUDE_PATH=/usr/include/eigen3"
  _opts="${_opts/-DCPU_BASELINE_DISABLE=SSE3/}" # per-arch options
  _opts="${_opts/-DCPU_BASELINE_REQUIRE=SSE2/}" # per-arch options
  _opts="${_opts/-DOPENCV_ENABLE_NONFREE=ON/-DOPENCV_ENABLE_NONFREE=OFF}" # non-free
  _opts+=" ${parabola_options}"                                           # non-free
# _opts+=' -DWITH_GAPI=OFF'

  # build 'ade'
  cmake -B build-ade -S ade-${_ade_ver}
  cmake --build build-ade

  # build 'opencv'
  cmake -B build -S $pkgname-$pkgver $_opts \
    -DBUILD_WITH_DEBUG_INFO=ON
  cmake --build build

  # 'build-cuda' recipe deleted (non-free)
}

package_opencv() {
  DESTDIR="$pkgdir" cmake --install build

  # install license file
  install -Dm644 $pkgbase-$pkgver/LICENSE -t "$pkgdir"/usr/share/licenses/$pkgname

  # separate samples package
  mv "$pkgdir"/usr/share/opencv4/samples "$srcdir"

  # Add java symlinks expected by some binary blobs
  ln -sr "$pkgdir"/usr/share/java/{opencv4/opencv-${pkgver//./},opencv}.jar
  ln -sr "$pkgdir"/usr/lib/{libopencv_java${pkgver//./},libopencv_java}.so

  # Split Python bindings
  rm -r "$pkgdir"/usr/lib/python3*
}

package_opencv-samples() {
  pkgdesc+=' (samples)'
  depends=(opencv)
  unset optdepends

  mkdir -p "$pkgdir"/usr/share/opencv4
  mv samples "$pkgdir"/usr/share/opencv4

  # install license file
  install -Dm644 $pkgbase-$pkgver/LICENSE -t "$pkgdir"/usr/share/licenses/$pkgname
}

package_python-opencv() {
  pkgdesc='Python bindings for OpenCV'
  depends=(python-numpy opencv vtk glew qt6-base hdf5 jsoncpp openmpi pugixml fmt)
  unset optdepends

  DESTDIR="$pkgdir" cmake --install build/modules/python3

  # install license file
  install -Dm644 $pkgbase-$pkgver/LICENSE -t "$pkgdir"/usr/share/licenses/$pkgname
}

# package_opencv-cuda() deleted (non-free)
