media-libs/opencv: version bump 3.3.0 bug #629534
authorAmy Liffey <amynka@gentoo.org>
Tue, 19 Sep 2017 07:46:54 +0000 (09:46 +0200)
committerAmy Liffey <amynka@gentoo.org>
Tue, 19 Sep 2017 07:52:19 +0000 (09:52 +0200)
- Patch for CVEs bug #627958
- Add required use for bug #621986
- Version bump fixes bug #627954

Closes: https://bugs.gentoo.org/629534

Package-Manager: Portage-2.3.6, Repoman-2.3.1

media-libs/opencv/Manifest
media-libs/opencv/files/opencv-3.3.0-contrib-xfeatures2d.patch [new file with mode: 0644]
media-libs/opencv/files/opencv-3.3.0-imgcodecs-gcc.patch [new file with mode: 0644]
media-libs/opencv/opencv-3.3.0.ebuild [new file with mode: 0644]

index a529669fefa955546f2e727c21358154e348b1c4..1f375ff71d5a93a991d0a2172dc25fc5d6ccf285 100644 (file)
@@ -4,4 +4,6 @@ DIST opencv-3.1.0.tar.gz 76135587 SHA256 f00b3c4f42acda07d89031a2ebb5ebe390764a1
 DIST opencv-3.1.0_contrib-75b3ea9.tar.gz 54277105 SHA256 478f742457d3f4e96f857b726e35b28a8d20a1de8e5f51b8671251bc896d443b SHA512 d1d11520b8729fbaf0257c927654251ff9ac1ba5cf937af9dd973ec39f483d1ee08aff7ad3f1a9941fef921a35dc466ac5574918197ddecd3f6c66b682bf671a WHIRLPOOL 18b70014428c4fa532658ca5ac332bffaae049b468f46cb027a6972f21f5b2bd17d02b33d68c43b84f821a77fa09efb9c372499cfa4f645a0516b93acb858353
 DIST opencv-3.2.0.tar.gz 78861546 SHA256 b9d62dfffb8130d59d587627703d5f3e6252dce4a94c1955784998da7a39dd35 SHA512 a338f4b4cdebfc2dcd763427b9c9632b3a3b0d072117b8e6367c73ea1ac21f7148553a23c7afbb44b01a48be3be95520789c2de1d6ae230b7b414ee713d3606d WHIRLPOOL 092c0c1195d80f89e0e2fd030a93eb80e7b83ce155fdcd9fa071248be20127a684922c83de73be9bf321d934e14b0b4e60cc78ab272ab9d39d6707da37db30d3
 DIST opencv-3.2.0_contrib.tar.gz 54765210 SHA256 1e2bb6c9a41c602904cc7df3f8fb8f98363a88ea564f2a087240483426bf8cbe SHA512 eadb6a8a3625235b0c71e29c36d15d9342278aaf9148ef6a7e1aa80f4db0491aaf30b6df16bfd0cd358402b2a3059b6acbce23fb5fe2c0c57150a733ffbbff5a WHIRLPOOL eb8f916c19474a58f4c2785e50dc261a31f684a917011473b94a19d26e4e9845c042f77196c000dd97543699b745360114cdd31cad549379b6394e9d727c72a8
+DIST opencv-3.3.0.tar.gz 81238534 SHA256 8bb312b9d9fd17336dc1f8b3ac82f021ca50e2034afc866098866176d985adc6 SHA512 13dee5c1c5fec1dccdbb05879d299b93ef8ddeb87f561a6c4178e33a4cf5ae919765119068d0387a3efea0e09a625ca993cffac60a772159690fcbee4e8d70fb WHIRLPOOL 211496e559fa3a78b662329a5e21613fdc39b616155584311f82f3d7c733676bcb58d8e04ffda2d73658933240e16122212413fa1c2e6dfe764439c9460d7c41
+DIST opencv-3.3.0_contrib.tar.gz 54848519 SHA256 e94acf39cd4854c3ef905e06516e5f74f26dddfa6477af89558fb40a57aeb444 SHA512 ebe3dbe6c754c6fbaabbf6b0d2a4209964e625fd68e593f30ce043792740c8c1d4440d7870949b5b33f488fd7e2e05f3752287b7f50dd24c29202e268776520e WHIRLPOOL b186f673e276c4b8c4c5253fd17181f0e1b7bd4a0e0c74f15ab55ea5f2ee54a72fc295247c7bfcbfbedba1fc01b4c5e2a53a2a4eff79ab0480977a6eefc90c58
 DIST vgg_boostdesc-3.2.0.tar.gz 1867770 SHA256 6da9c2465e2b36330fa5d5c45320a0667da5cb4eafd66a5b1f45feb2af047a27 SHA512 4a046aedd639c8eb4b295b0f499e756deb66210ca083f0124c75531e540663367cb58f6d175f66c4713324177036cd89a8869bdab2de8d1736dafc7f00ef9f44 WHIRLPOOL 5c78e43c95d40d103ac741248deb130bcb49a5b7e2cd012135572630b525b6f15a7f89948170c76545d97eb3815a000a2a1236ad24de2205eeb8938ee8eb0c12
diff --git a/media-libs/opencv/files/opencv-3.3.0-contrib-xfeatures2d.patch b/media-libs/opencv/files/opencv-3.3.0-contrib-xfeatures2d.patch
new file mode 100644 (file)
index 0000000..26e4ac7
--- /dev/null
@@ -0,0 +1,19 @@
+--- a/modules/xfeatures2d/CMakeLists.txt       2017-09-16 14:28:38.440000000 +0200
++++ b/modules/xfeatures2d/CMakeLists.txt       2017-09-16 14:27:21.350000000 +0200
+@@ -2,11 +2,11 @@
+ ocv_define_module(xfeatures2d opencv_core opencv_imgproc opencv_features2d opencv_calib3d OPTIONAL opencv_shape opencv_cudaarithm WRAP python java)
++#include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/download_vgg.cmake)
++#include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/download_boostdesc.cmake)
++#set(DOWNLOAD_DIR "${OpenCV_BINARY_DIR}/downloads/xfeatures2d")
++#download_boost_descriptors("${DOWNLOAD_DIR}" boost_status)
++#download_vgg_descriptors("${DOWNLOAD_DIR}" vgg_status)
+-include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/download_vgg.cmake)
+-include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/download_boostdesc.cmake)
+-set(DOWNLOAD_DIR "${OpenCV_BINARY_DIR}/downloads/xfeatures2d")
+-download_boost_descriptors("${DOWNLOAD_DIR}" boost_status)
+-download_vgg_descriptors("${DOWNLOAD_DIR}" vgg_status)
+ if(NOT boost_status OR NOT vgg_status)
+   ocv_module_disable(xfeatures2d)
+ endif()
diff --git a/media-libs/opencv/files/opencv-3.3.0-imgcodecs-gcc.patch b/media-libs/opencv/files/opencv-3.3.0-imgcodecs-gcc.patch
new file mode 100644 (file)
index 0000000..d4ec2fe
--- /dev/null
@@ -0,0 +1,902 @@
+From 0d854db361106dfcb055231fd0112c5b85ef2287 Mon Sep 17 00:00:00 2001
+From: Alexander Alekhin <alexander.a.alekhin@gmail.com>
+Date: Tue, 15 Aug 2017 21:45:05 +0000
+Subject: [PATCH 1/3] build: workaround GCC 7.1.1 compilation issue with
+ sanitize flags
+
+Version: gcc (GCC) 7.1.1 20170622 (Red Hat 7.1.1-3)
+Flags: -fsanitize=address,undefined
+---
+ modules/ts/src/cuda_test.cpp | 56 ++++++++++++++++++++++++++------------------
+ 1 file changed, 33 insertions(+), 23 deletions(-)
+
+diff --git a/modules/ts/src/cuda_test.cpp b/modules/ts/src/cuda_test.cpp
+index a48e0a08719..eb4cee13622 100644
+--- a/modules/ts/src/cuda_test.cpp
++++ b/modules/ts/src/cuda_test.cpp
+@@ -322,16 +322,20 @@ namespace cvtest
+         if (m1.size() != m2.size())
+         {
+-            return AssertionFailure() << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different sizes : \""
+-                                      << expr1 << "\" [" << PrintToString(m1.size()) << "] vs \""
+-                                      << expr2 << "\" [" << PrintToString(m2.size()) << "]";
++            std::stringstream msg;
++            msg << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different sizes : \""
++                << expr1 << "\" [" << PrintToString(m1.size()) << "] vs \""
++                << expr2 << "\" [" << PrintToString(m2.size()) << "]";
++            return AssertionFailure() << msg.str();
+         }
+         if (m1.type() != m2.type())
+         {
+-            return AssertionFailure() << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different types : \""
+-                                      << expr1 << "\" [" << PrintToString(MatType(m1.type())) << "] vs \""
+-                                      << expr2 << "\" [" << PrintToString(MatType(m2.type())) << "]";
++            std::stringstream msg;
++            msg << "Matrices \"" << expr1 << "\" and \"" << expr2 << "\" have different types : \""
++                << expr1 << "\" [" << PrintToString(MatType(m1.type())) << "] vs \""
++                << expr2 << "\" [" << PrintToString(MatType(m2.type())) << "]";
++             return AssertionFailure() << msg.str();
+         }
+         Mat diff;
+@@ -343,12 +347,14 @@ namespace cvtest
+         if (maxVal > eps)
+         {
+-            return AssertionFailure() << "The max difference between matrices \"" << expr1 << "\" and \"" << expr2
+-                                      << "\" is " << maxVal << " at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ")"
+-                                      << ", which exceeds \"" << eps_expr << "\", where \""
+-                                      << expr1 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m1, maxLoc) << ", \""
+-                                      << expr2 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m2, maxLoc) << ", \""
+-                                      << eps_expr << "\" evaluates to " << eps;
++            std::stringstream msg;
++            msg << "The max difference between matrices \"" << expr1 << "\" and \"" << expr2
++                << "\" is " << maxVal << " at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ")"
++                << ", which exceeds \"" << eps_expr << "\", where \""
++                << expr1 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m1, maxLoc) << ", \""
++                << expr2 << "\" at (" << maxLoc.y << ", " << maxLoc.x / m1.channels() << ") evaluates to " << printMatVal(m2, maxLoc) << ", \""
++                << eps_expr << "\" evaluates to " << eps;
++            return AssertionFailure() << msg.str();
+         }
+         return AssertionSuccess();
+@@ -469,9 +475,11 @@ namespace cvtest
+     {
+         if (gold.size() != actual.size())
+         {
+-            return testing::AssertionFailure() << "KeyPoints size mistmach\n"
+-                                               << "\"" << gold_expr << "\" : " << gold.size() << "\n"
+-                                               << "\"" << actual_expr << "\" : " << actual.size();
++            std::stringstream msg;
++            msg << "KeyPoints size mistmach\n"
++                << "\"" << gold_expr << "\" : " << gold.size() << "\n"
++                << "\"" << actual_expr << "\" : " << actual.size();
++            return AssertionFailure() << msg.str();
+         }
+         std::sort(actual.begin(), actual.end(), KeyPointLess());
+@@ -484,14 +492,16 @@ namespace cvtest
+             if (!keyPointsEquals(p1, p2))
+             {
+-                return testing::AssertionFailure() << "KeyPoints differ at " << i << "\n"
+-                                                   << "\"" << gold_expr << "\" vs \"" << actual_expr << "\" : \n"
+-                                                   << "pt : " << testing::PrintToString(p1.pt) << " vs " << testing::PrintToString(p2.pt) << "\n"
+-                                                   << "size : " << p1.size << " vs " << p2.size << "\n"
+-                                                   << "angle : " << p1.angle << " vs " << p2.angle << "\n"
+-                                                   << "response : " << p1.response << " vs " << p2.response << "\n"
+-                                                   << "octave : " << p1.octave << " vs " << p2.octave << "\n"
+-                                                   << "class_id : " << p1.class_id << " vs " << p2.class_id;
++                std::stringstream msg;
++                msg << "KeyPoints differ at " << i << "\n"
++                    << "\"" << gold_expr << "\" vs \"" << actual_expr << "\" : \n"
++                    << "pt : " << testing::PrintToString(p1.pt) << " vs " << testing::PrintToString(p2.pt) << "\n"
++                    << "size : " << p1.size << " vs " << p2.size << "\n"
++                    << "angle : " << p1.angle << " vs " << p2.angle << "\n"
++                    << "response : " << p1.response << " vs " << p2.response << "\n"
++                    << "octave : " << p1.octave << " vs " << p2.octave << "\n"
++                    << "class_id : " << p1.class_id << " vs " << p2.class_id;
++                return AssertionFailure() << msg.str();
+             }
+         }
+
+From 999f41fb4f4aa94a0cb47256919ae8b5c29ca5f3 Mon Sep 17 00:00:00 2001
+From: Alexander Alekhin <alexander.a.alekhin@gmail.com>
+Date: Tue, 15 Aug 2017 22:04:55 +0000
+Subject: [PATCH 2/3] imgcodecs: refactoring, improve code quality
+
+---
+ modules/imgcodecs/src/bitstrm.cpp   |   2 +
+ modules/imgcodecs/src/bitstrm.hpp   |  19 +++--
+ modules/imgcodecs/src/grfmt_bmp.cpp |  13 ++-
+ modules/imgcodecs/src/grfmt_pxm.cpp | 122 ++++++++++++++++-----------
+ modules/imgcodecs/src/loadsave.cpp  | 164 +++++++++++++++++++++++++++++-------
+ 5 files changed, 231 insertions(+), 89 deletions(-)
+
+diff --git a/modules/imgcodecs/src/bitstrm.cpp b/modules/imgcodecs/src/bitstrm.cpp
+index a7e187fa0cf..0a8941aecf8 100644
+--- a/modules/imgcodecs/src/bitstrm.cpp
++++ b/modules/imgcodecs/src/bitstrm.cpp
+@@ -209,6 +209,8 @@ int  RLByteStream::getByte()
+         current = m_current;
+     }
++    CV_Assert(current < m_end);
++
+     val = *((uchar*)current);
+     m_current = current + 1;
+     return val;
+diff --git a/modules/imgcodecs/src/bitstrm.hpp b/modules/imgcodecs/src/bitstrm.hpp
+index 465c0a847ba..26947971f35 100644
+--- a/modules/imgcodecs/src/bitstrm.hpp
++++ b/modules/imgcodecs/src/bitstrm.hpp
+@@ -48,13 +48,20 @@
+ namespace cv
+ {
+-enum
+-{
+-    RBS_THROW_EOS=-123,  // <end of stream> exception code
+-    RBS_THROW_FORB=-124,  // <forrbidden huffman code> exception code
+-    RBS_HUFF_FORB=2047,  // forrbidden huffman code "value"
+-    RBS_BAD_HEADER=-125 // invalid header
++#define DECLARE_RBS_EXCEPTION(name) \
++class RBS_ ## name ## _Exception : public cv::Exception \
++{ \
++public: \
++    RBS_ ## name ## _Exception(int code_, const String& err_, const String& func_, const String& file_, int line_) : \
++        cv::Exception(code_, err_, func_, file_, line_) \
++    {} \
+ };
++DECLARE_RBS_EXCEPTION(THROW_EOS)
++#define RBS_THROW_EOS RBS_THROW_EOS_Exception(cv::Error::StsError, "Unexpected end of input stream", CV_Func, __FILE__, __LINE__)
++DECLARE_RBS_EXCEPTION(THROW_FORB)
++#define RBS_THROW_FORB RBS_THROW_FORB_Exception(cv::Error::StsError, "Forrbidden huffman code", CV_Func, __FILE__, __LINE__)
++DECLARE_RBS_EXCEPTION(BAD_HEADER)
++#define RBS_BAD_HEADER RBS_BAD_HEADER_Exception(cv::Error::StsError, "Invalid header", CV_Func, __FILE__, __LINE__)
+ typedef unsigned long ulong;
+diff --git a/modules/imgcodecs/src/grfmt_bmp.cpp b/modules/imgcodecs/src/grfmt_bmp.cpp
+index 86cacd31685..257f97c2d8b 100644
+--- a/modules/imgcodecs/src/grfmt_bmp.cpp
++++ b/modules/imgcodecs/src/grfmt_bmp.cpp
+@@ -118,8 +118,9 @@ bool  BmpDecoder::readHeader()
+                 if( m_bpp <= 8 )
+                 {
+-                    memset( m_palette, 0, sizeof(m_palette));
+-                    m_strm.getBytes( m_palette, (clrused == 0? 1<<m_bpp : clrused)*4 );
++                    CV_Assert(clrused < 256);
++                    memset(m_palette, 0, sizeof(m_palette));
++                    m_strm.getBytes(m_palette, (clrused == 0? 1<<m_bpp : clrused)*4 );
+                     iscolor = IsColorPalette( m_palette, m_bpp );
+                 }
+                 else if( m_bpp == 16 && m_rle_code == BMP_BITFIELDS )
+@@ -290,7 +291,9 @@ bool  BmpDecoder::readData( Mat& img )
+                     else if( code > 2 ) // absolute mode
+                     {
+                         if( data + code*nch > line_end ) goto decode_rle4_bad;
+-                        m_strm.getBytes( src, (((code + 1)>>1) + 1) & -2 );
++                        int sz = (((code + 1)>>1) + 1) & (~1);
++                        CV_Assert((size_t)sz < _src.size());
++                        m_strm.getBytes(src, sz);
+                         if( color )
+                             data = FillColorRow4( data, src, code, m_palette );
+                         else
+@@ -379,7 +382,9 @@ decode_rle4_bad: ;
+                         if( data + code3 > line_end )
+                             goto decode_rle8_bad;
+-                        m_strm.getBytes( src, (code + 1) & -2 );
++                        int sz = (code + 1) & (~1);
++                        CV_Assert((size_t)sz < _src.size());
++                        m_strm.getBytes(src, sz);
+                         if( color )
+                             data = FillColorRow8( data, src, code, m_palette );
+                         else
+diff --git a/modules/imgcodecs/src/grfmt_pxm.cpp b/modules/imgcodecs/src/grfmt_pxm.cpp
+index 1750cb705c3..68bd8fd93f5 100644
+--- a/modules/imgcodecs/src/grfmt_pxm.cpp
++++ b/modules/imgcodecs/src/grfmt_pxm.cpp
+@@ -43,50 +43,58 @@
+ #include "precomp.hpp"
+ #include "utils.hpp"
+ #include "grfmt_pxm.hpp"
++#include <iostream>
+ namespace cv
+ {
+ ///////////////////////// P?M reader //////////////////////////////
+-static int ReadNumber( RLByteStream& strm, int maxdigits )
++static int ReadNumber(RLByteStream& strm, int maxdigits = 0)
+ {
+     int code;
+-    int val = 0;
++    int64 val = 0;
+     int digits = 0;
+     code = strm.getByte();
+-    if( !isdigit(code))
++    while (!isdigit(code))
+     {
+-        do
++        if (code == '#' )
+         {
+-            if( code == '#' )
++            do
+             {
+-                do
+-                {
+-                    code = strm.getByte();
+-                }
+-                while( code != '\n' && code != '\r' );
++                code = strm.getByte();
+             }
+-
++            while (code != '\n' && code != '\r');
+             code = strm.getByte();
+-
+-            while( isspace(code))
++        }
++        else if (isspace(code))
++        {
++            while (isspace(code))
+                 code = strm.getByte();
+         }
+-        while( !isdigit( code ));
++        else
++        {
++#if 1
++            CV_ErrorNoReturn_(Error::StsError, ("PXM: Unexpected code in ReadNumber(): 0x%x (%d)", code, code));
++#else
++            code = strm.getByte();
++#endif
++        }
+     }
+     do
+     {
+-        val = val*10 + code - '0';
+-        if( ++digits >= maxdigits ) break;
++        val = val*10 + (code - '0');
++        CV_Assert(val <= INT_MAX && "PXM: ReadNumber(): result is too large");
++        digits++;
++        if (maxdigits != 0 && digits >= maxdigits) break;
+         code = strm.getByte();
+     }
+-    while( isdigit(code));
++    while (isdigit(code));
+-    return val;
++    return (int)val;
+ }
+@@ -122,13 +130,13 @@ ImageDecoder PxMDecoder::newDecoder() const
+     return makePtr<PxMDecoder>();
+ }
+-void  PxMDecoder::close()
++void PxMDecoder::close()
+ {
+     m_strm.close();
+ }
+-bool  PxMDecoder::readHeader()
++bool PxMDecoder::readHeader()
+ {
+     bool result = false;
+@@ -158,10 +166,10 @@ bool  PxMDecoder::readHeader()
+         m_binary = code >= '4';
+         m_type = m_bpp > 8 ? CV_8UC3 : CV_8UC1;
+-        m_width = ReadNumber( m_strm, INT_MAX );
+-        m_height = ReadNumber( m_strm, INT_MAX );
++        m_width = ReadNumber(m_strm);
++        m_height = ReadNumber(m_strm);
+-        m_maxval = m_bpp == 1 ? 1 : ReadNumber( m_strm, INT_MAX );
++        m_maxval = m_bpp == 1 ? 1 : ReadNumber(m_strm);
+         if( m_maxval > 65535 )
+             throw RBS_BAD_HEADER;
+@@ -175,8 +183,14 @@ bool  PxMDecoder::readHeader()
+             result = true;
+         }
+     }
+-    catch(...)
++    catch (const cv::Exception&)
++    {
++        throw;
++    }
++    catch (...)
+     {
++        std::cerr << "PXM::readHeader(): unknown C++ exception" << std::endl << std::flush;
++        throw;
+     }
+     if( !result )
+@@ -189,33 +203,28 @@ bool  PxMDecoder::readHeader()
+ }
+-bool  PxMDecoder::readData( Mat& img )
++bool PxMDecoder::readData( Mat& img )
+ {
+     int color = img.channels() > 1;
+     uchar* data = img.ptr();
+     PaletteEntry palette[256];
+     bool   result = false;
+-    int  bit_depth = CV_ELEM_SIZE1(m_type)*8;
+-    int  src_pitch = (m_width*m_bpp*bit_depth/8 + 7)/8;
++    const int bit_depth = CV_ELEM_SIZE1(m_type)*8;
++    const int src_pitch = divUp(m_width*m_bpp*(bit_depth/8), 8);
+     int  nch = CV_MAT_CN(m_type);
+     int  width3 = m_width*nch;
+-    int  i, x, y;
+     if( m_offset < 0 || !m_strm.isOpened())
+         return false;
+-    AutoBuffer<uchar> _src(src_pitch + 32);
+-    uchar* src = _src;
+-    AutoBuffer<uchar> _gray_palette;
+-    uchar* gray_palette = _gray_palette;
++    uchar gray_palette[256] = {0};
+     // create LUT for converting colors
+     if( bit_depth == 8 )
+     {
+-        _gray_palette.allocate(m_maxval + 1);
+-        gray_palette = _gray_palette;
++        CV_Assert(m_maxval < 256);
+-        for( i = 0; i <= m_maxval; i++ )
++        for (int i = 0; i <= m_maxval; i++)
+             gray_palette[i] = (uchar)((i*255/m_maxval)^(m_bpp == 1 ? 255 : 0));
+         FillGrayPalette( palette, m_bpp==1 ? 1 : 8 , m_bpp == 1 );
+@@ -229,12 +238,16 @@ bool  PxMDecoder::readData( Mat& img )
+         {
+         ////////////////////////// 1 BPP /////////////////////////
+         case 1:
++            CV_Assert(CV_MAT_DEPTH(m_type) == CV_8U);
+             if( !m_binary )
+             {
+-                for( y = 0; y < m_height; y++, data += img.step )
++                AutoBuffer<uchar> _src(m_width);
++                uchar* src = _src;
++
++                for (int y = 0; y < m_height; y++, data += img.step)
+                 {
+-                    for( x = 0; x < m_width; x++ )
+-                        src[x] = ReadNumber( m_strm, 1 ) != 0;
++                    for (int x = 0; x < m_width; x++)
++                        src[x] = ReadNumber(m_strm, 1) != 0;
+                     if( color )
+                         FillColorRow8( data, src, m_width, palette );
+@@ -244,7 +257,10 @@ bool  PxMDecoder::readData( Mat& img )
+             }
+             else
+             {
+-                for( y = 0; y < m_height; y++, data += img.step )
++                AutoBuffer<uchar> _src(src_pitch);
++                uchar* src = _src;
++
++                for (int y = 0; y < m_height; y++, data += img.step)
+                 {
+                     m_strm.getBytes( src, src_pitch );
+@@ -260,13 +276,17 @@ bool  PxMDecoder::readData( Mat& img )
+         ////////////////////////// 8 BPP /////////////////////////
+         case 8:
+         case 24:
+-            for( y = 0; y < m_height; y++, data += img.step )
++        {
++            AutoBuffer<uchar> _src(std::max<size_t>(width3*2, src_pitch));
++            uchar* src = _src;
++
++            for (int y = 0; y < m_height; y++, data += img.step)
+             {
+                 if( !m_binary )
+                 {
+-                    for( x = 0; x < width3; x++ )
++                    for (int x = 0; x < width3; x++)
+                     {
+-                        int code = ReadNumber( m_strm, INT_MAX );
++                        int code = ReadNumber(m_strm);
+                         if( (unsigned)code > (unsigned)m_maxval ) code = m_maxval;
+                         if( bit_depth == 8 )
+                             src[x] = gray_palette[code];
+@@ -279,7 +299,7 @@ bool  PxMDecoder::readData( Mat& img )
+                     m_strm.getBytes( src, src_pitch );
+                     if( bit_depth == 16 && !isBigEndian() )
+                     {
+-                        for( x = 0; x < width3; x++ )
++                        for (int x = 0; x < width3; x++)
+                         {
+                             uchar v = src[x * 2];
+                             src[x * 2] = src[x * 2 + 1];
+@@ -290,7 +310,7 @@ bool  PxMDecoder::readData( Mat& img )
+                 if( img.depth() == CV_8U && bit_depth == 16 )
+                 {
+-                    for( x = 0; x < width3; x++ )
++                    for (int x = 0; x < width3; x++)
+                     {
+                         int v = ((ushort *)src)[x];
+                         src[x] = (uchar)(v >> 8);
+@@ -331,12 +351,19 @@ bool  PxMDecoder::readData( Mat& img )
+             }
+             result = true;
+             break;
++        }
+         default:
+-            assert(0);
++            CV_ErrorNoReturn(Error::StsError, "m_bpp is not supported");
+         }
+     }
+-    catch(...)
++    catch (const cv::Exception&)
++    {
++        throw;
++    }
++    catch (...)
+     {
++        std::cerr << "PXM::readData(): unknown exception" << std::endl << std::flush;
++        throw;
+     }
+     return result;
+@@ -412,8 +439,9 @@ bool  PxMEncoder::write( const Mat& img, const std::vector<int>& params )
+     char* buffer = _buffer;
+     // write header;
+-    sprintf( buffer, "P%c\n%d %d\n%d\n",
++    sprintf( buffer, "P%c\n# Generated by OpenCV %s\n%d %d\n%d\n",
+              '2' + (channels > 1 ? 1 : 0) + (isBinary ? 3 : 0),
++             CV_VERSION,
+              width, height, (1 << depth) - 1 );
+     strm.putBytes( buffer, (int)strlen(buffer) );
+diff --git a/modules/imgcodecs/src/loadsave.cpp b/modules/imgcodecs/src/loadsave.cpp
+index 3b2366217f2..5ee4ca3541b 100644
+--- a/modules/imgcodecs/src/loadsave.cpp
++++ b/modules/imgcodecs/src/loadsave.cpp
+@@ -55,6 +55,27 @@
+ /****************************************************************************************\
+ *                                      Image Codecs                                      *
+ \****************************************************************************************/
++
++namespace cv {
++
++// TODO Add runtime configuration
++#define CV_IO_MAX_IMAGE_PARAMS (50)
++#define CV_IO_MAX_IMAGE_WIDTH (1<<20)
++#define CV_IO_MAX_IMAGE_HEIGHT (1<<20)
++#define CV_IO_MAX_IMAGE_PIXELS (1<<30) // 1 Gigapixel
++
++static Size validateInputImageSize(const Size& size)
++{
++    CV_Assert(size.width > 0);
++    CV_Assert(size.width <= CV_IO_MAX_IMAGE_WIDTH);
++    CV_Assert(size.height > 0);
++    CV_Assert(size.height <= CV_IO_MAX_IMAGE_HEIGHT);
++    uint64 pixels = (uint64)size.width * (uint64)size.height;
++    CV_Assert(pixels <= CV_IO_MAX_IMAGE_PIXELS);
++    return size;
++}
++
++
+ namespace {
+ class ByteStreamBuffer: public std::streambuf
+@@ -94,9 +115,6 @@ class ByteStreamBuffer: public std::streambuf
+ }
+-namespace cv
+-{
+-
+ /**
+  * @struct ImageCodecInitializer
+  *
+@@ -408,14 +426,26 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 )
+     /// set the filename in the driver
+     decoder->setSource( filename );
+-   // read the header to make sure it succeeds
+-   if( !decoder->readHeader() )
++    try
++    {
++        // read the header to make sure it succeeds
++        if( !decoder->readHeader() )
++            return 0;
++    }
++    catch (const cv::Exception& e)
++    {
++        std::cerr << "imread_('" << filename << "'): can't read header: " << e.what() << std::endl << std::flush;
+         return 0;
++    }
++    catch (...)
++    {
++        std::cerr << "imread_('" << filename << "'): can't read header: unknown exception" << std::endl << std::flush;
++        return 0;
++    }
++
+     // established the required input image size
+-    CvSize size;
+-    size.width = decoder->width();
+-    size.height = decoder->height();
++    Size size = validateInputImageSize(Size(decoder->width(), decoder->height()));
+     // grab the decoded type
+     int type = decoder->type();
+@@ -451,7 +481,21 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 )
+     }
+     // read the image data
+-    if( !decoder->readData( *data ))
++    bool success = false;
++    try
++    {
++        if (decoder->readData(*data))
++            success = true;
++    }
++    catch (const cv::Exception& e)
++    {
++        std::cerr << "imread_('" << filename << "'): can't read data: " << e.what() << std::endl << std::flush;
++    }
++    catch (...)
++    {
++        std::cerr << "imread_('" << filename << "'): can't read data: unknown exception" << std::endl << std::flush;
++    }
++    if (!success)
+     {
+         cvReleaseImage( &image );
+         cvReleaseMat( &matrix );
+@@ -504,8 +548,22 @@ imreadmulti_(const String& filename, int flags, std::vector<Mat>& mats)
+     decoder->setSource(filename);
+     // read the header to make sure it succeeds
+-    if (!decoder->readHeader())
++    try
++    {
++        // read the header to make sure it succeeds
++        if( !decoder->readHeader() )
++            return 0;
++    }
++    catch (const cv::Exception& e)
++    {
++        std::cerr << "imreadmulti_('" << filename << "'): can't read header: " << e.what() << std::endl << std::flush;
+         return 0;
++    }
++    catch (...)
++    {
++        std::cerr << "imreadmulti_('" << filename << "'): can't read header: unknown exception" << std::endl << std::flush;
++        return 0;
++    }
+     for (;;)
+     {
+@@ -523,17 +581,32 @@ imreadmulti_(const String& filename, int flags, std::vector<Mat>& mats)
+                 type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
+         }
++        // established the required input image size
++        Size size = validateInputImageSize(Size(decoder->width(), decoder->height()));
++
+         // read the image data
+-        Mat mat(decoder->height(), decoder->width(), type);
+-        if (!decoder->readData(mat))
++        Mat mat(size.height, size.width, type);
++        bool success = false;
++        try
+         {
+-            // optionally rotate the data if EXIF' orientation flag says so
+-            if( (flags & IMREAD_IGNORE_ORIENTATION) == 0 && flags != IMREAD_UNCHANGED )
+-            {
+-                ApplyExifOrientation(filename, mat);
+-            }
+-
++            if (decoder->readData(mat))
++                success = true;
++        }
++        catch (const cv::Exception& e)
++        {
++            std::cerr << "imreadmulti_('" << filename << "'): can't read data: " << e.what() << std::endl << std::flush;
++        }
++        catch (...)
++        {
++            std::cerr << "imreadmulti_('" << filename << "'): can't read data: unknown exception" << std::endl << std::flush;
++        }
++        if (!success)
+             break;
++
++        // optionally rotate the data if EXIF' orientation flag says so
++        if( (flags & IMREAD_IGNORE_ORIENTATION) == 0 && flags != IMREAD_UNCHANGED )
++        {
++            ApplyExifOrientation(filename, mat);
+         }
+         mats.push_back(mat);
+@@ -616,6 +689,7 @@ static bool imwrite_( const String& filename, const Mat& image,
+     }
+     encoder->setDestination( filename );
++    CV_Assert(params.size() <= CV_IO_MAX_IMAGE_PARAMS*2);
+     bool code = encoder->write( *pimage, params );
+     //    CV_Assert( code );
+@@ -663,22 +737,35 @@ imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 )
+         decoder->setSource(filename);
+     }
+-    if( !decoder->readHeader() )
++    bool success = false;
++    try
++    {
++        if (decoder->readHeader())
++            success = true;
++    }
++    catch (const cv::Exception& e)
++    {
++        std::cerr << "imdecode_('" << filename << "'): can't read header: " << e.what() << std::endl << std::flush;
++    }
++    catch (...)
++    {
++        std::cerr << "imdecode_('" << filename << "'): can't read header: unknown exception" << std::endl << std::flush;
++    }
++    if (!success)
+     {
+         decoder.release();
+-        if ( !filename.empty() )
++        if (!filename.empty())
+         {
+-            if ( remove(filename.c_str()) != 0 )
++            if (0 != remove(filename.c_str()))
+             {
+-                CV_Error( CV_StsError, "unable to remove temporary file" );
++                std::cerr << "unable to remove temporary file:" << filename << std::endl << std::flush;
+             }
+         }
+         return 0;
+     }
+-    CvSize size;
+-    size.width = decoder->width();
+-    size.height = decoder->height();
++    // established the required input image size
++    Size size = validateInputImageSize(Size(decoder->width(), decoder->height()));
+     int type = decoder->type();
+     if( (flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED )
+@@ -712,17 +799,30 @@ imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 )
+         temp = cvarrToMat(image);
+     }
+-    bool code = decoder->readData( *data );
++    success = false;
++    try
++    {
++        if (decoder->readData(*data))
++            success = true;
++    }
++    catch (const cv::Exception& e)
++    {
++        std::cerr << "imdecode_('" << filename << "'): can't read data: " << e.what() << std::endl << std::flush;
++    }
++    catch (...)
++    {
++        std::cerr << "imdecode_('" << filename << "'): can't read data: unknown exception" << std::endl << std::flush;
++    }
+     decoder.release();
+-    if ( !filename.empty() )
++    if (!filename.empty())
+     {
+-        if ( remove(filename.c_str()) != 0 )
++        if (0 != remove(filename.c_str()))
+         {
+-            CV_Error( CV_StsError, "unable to remove temporary file" );
++            std::cerr << "unable to remove temporary file:" << filename << std::endl << std::flush;
+         }
+     }
+-    if( !code )
++    if (!success)
+     {
+         cvReleaseImage( &image );
+         cvReleaseMat( &matrix );
+@@ -859,7 +959,7 @@ cvSaveImage( const char* filename, const CvArr* arr, const int* _params )
+     if( _params )
+     {
+         for( ; _params[i] > 0; i += 2 )
+-            ;
++            CV_Assert(i < CV_IO_MAX_IMAGE_PARAMS*2); // Limit number of params for security reasons
+     }
+     return cv::imwrite_(filename, cv::cvarrToMat(arr),
+         i > 0 ? std::vector<int>(_params, _params+i) : std::vector<int>(),
+@@ -890,7 +990,7 @@ cvEncodeImage( const char* ext, const CvArr* arr, const int* _params )
+     if( _params )
+     {
+         for( ; _params[i] > 0; i += 2 )
+-            ;
++            CV_Assert(i < CV_IO_MAX_IMAGE_PARAMS*2); // Limit number of params for security reasons
+     }
+     cv::Mat img = cv::cvarrToMat(arr);
+     if( CV_IS_IMAGE(arr) && ((const IplImage*)arr)->origin == IPL_ORIGIN_BL )
+
+From 78a310630fb0a1f6d089576202343e672f27609d Mon Sep 17 00:00:00 2001
+From: Alexander Alekhin <alexander.alekhin@intel.com>
+Date: Wed, 16 Aug 2017 13:53:12 +0300
+Subject: [PATCH 3/3] imgproc(test): add checks for remove() call
+
+---
+ modules/imgcodecs/test/test_grfmt.cpp      |  2 +-
+ modules/imgcodecs/test/test_jpeg.cpp       | 12 ++++++------
+ modules/imgcodecs/test/test_png.cpp        |  2 +-
+ modules/imgcodecs/test/test_read_write.cpp |  4 ++--
+ modules/imgcodecs/test/test_tiff.cpp       |  8 ++++----
+ modules/imgcodecs/test/test_webp.cpp       |  6 +++---
+ 6 files changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/modules/imgcodecs/test/test_grfmt.cpp b/modules/imgcodecs/test/test_grfmt.cpp
+index 64a0c1e3ad0..74b72c3b3e9 100644
+--- a/modules/imgcodecs/test/test_grfmt.cpp
++++ b/modules/imgcodecs/test/test_grfmt.cpp
+@@ -175,7 +175,7 @@ TEST_P(Imgcodecs_ExtSize, write_imageseq)
+             EXPECT_LT(n, 1.);
+             EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, img_gt);
+         }
+-        remove(filename.c_str());
++        EXPECT_EQ(0, remove(filename.c_str()));
+     }
+ }
+diff --git a/modules/imgcodecs/test/test_jpeg.cpp b/modules/imgcodecs/test/test_jpeg.cpp
+index 5546f2d91a8..6ddb0284020 100644
+--- a/modules/imgcodecs/test/test_jpeg.cpp
++++ b/modules/imgcodecs/test/test_jpeg.cpp
+@@ -123,8 +123,8 @@ TEST(Imgcodecs_Jpeg, encode_decode_progressive_jpeg)
+     EXPECT_EQ(0, cvtest::norm(img_jpg_progressive, img_jpg_normal, NORM_INF));
+-    remove(output_progressive.c_str());
+-    remove(output_normal.c_str());
++    EXPECT_EQ(0, remove(output_progressive.c_str()));
++    EXPECT_EQ(0, remove(output_normal.c_str()));
+ }
+ TEST(Imgcodecs_Jpeg, encode_decode_optimize_jpeg)
+@@ -148,8 +148,8 @@ TEST(Imgcodecs_Jpeg, encode_decode_optimize_jpeg)
+     EXPECT_EQ(0, cvtest::norm(img_jpg_optimized, img_jpg_normal, NORM_INF));
+-    remove(output_optimized.c_str());
+-    remove(output_normal.c_str());
++    EXPECT_EQ(0, remove(output_optimized.c_str()));
++    EXPECT_EQ(0, remove(output_normal.c_str()));
+ }
+ TEST(Imgcodecs_Jpeg, encode_decode_rst_jpeg)
+@@ -173,8 +173,8 @@ TEST(Imgcodecs_Jpeg, encode_decode_rst_jpeg)
+     EXPECT_EQ(0, cvtest::norm(img_jpg_rst, img_jpg_normal, NORM_INF));
+-    remove(output_rst.c_str());
+-    remove(output_normal.c_str());
++    EXPECT_EQ(0, remove(output_rst.c_str()));
++    EXPECT_EQ(0, remove(output_normal.c_str()));
+ }
+ #endif // HAVE_JPEG
+diff --git a/modules/imgcodecs/test/test_png.cpp b/modules/imgcodecs/test/test_png.cpp
+index c46f901199e..4e97043e1c7 100644
+--- a/modules/imgcodecs/test/test_png.cpp
++++ b/modules/imgcodecs/test/test_png.cpp
+@@ -17,7 +17,7 @@ TEST(Imgcodecs_Png, write_big)
+     EXPECT_EQ(13043, img.cols);
+     EXPECT_EQ(13917, img.rows);
+     ASSERT_NO_THROW(imwrite(dst_file, img));
+-    remove(dst_file.c_str());
++    EXPECT_EQ(0, remove(dst_file.c_str()));
+ }
+ TEST(Imgcodecs_Png, encode)
+diff --git a/modules/imgcodecs/test/test_read_write.cpp b/modules/imgcodecs/test/test_read_write.cpp
+index 38f10225f68..5119813bf84 100644
+--- a/modules/imgcodecs/test/test_read_write.cpp
++++ b/modules/imgcodecs/test/test_read_write.cpp
+@@ -50,7 +50,7 @@ TEST(Imgcodecs_Image, read_write_bmp)
+         psnr = cvtest::PSNR(buf_loaded, image);
+         EXPECT_GT(psnr, thresDbell);
+-        remove(dst_name.c_str());
++        EXPECT_EQ(0, remove(dst_name.c_str()));
+     }
+ }
+@@ -95,7 +95,7 @@ TEST_P(Imgcodecs_Image, read_write)
+     psnr = cvtest::PSNR(buf_loaded, image);
+     EXPECT_GT(psnr, thresDbell);
+-    remove(full_name.c_str());
++    EXPECT_EQ(0, remove(full_name.c_str()));
+ }
+ const string exts[] = {
+diff --git a/modules/imgcodecs/test/test_tiff.cpp b/modules/imgcodecs/test/test_tiff.cpp
+index 0264da4cd81..6ef0c174828 100644
+--- a/modules/imgcodecs/test/test_tiff.cpp
++++ b/modules/imgcodecs/test/test_tiff.cpp
+@@ -41,8 +41,8 @@ TEST(Imgcodecs_Tiff, decode_tile16384x16384)
+         // not enough memory
+     }
+-    remove(file3.c_str());
+-    remove(file4.c_str());
++    EXPECT_EQ(0, remove(file3.c_str()));
++    EXPECT_EQ(0, remove(file4.c_str()));
+ }
+ TEST(Imgcodecs_Tiff, write_read_16bit_big_little_endian)
+@@ -88,7 +88,7 @@ TEST(Imgcodecs_Tiff, write_read_16bit_big_little_endian)
+         EXPECT_EQ(0xDEAD, img.at<ushort>(0,0));
+         EXPECT_EQ(0xBEEF, img.at<ushort>(0,1));
+-        remove(filename.c_str());
++        EXPECT_EQ(0, remove(filename.c_str()));
+     }
+ }
+@@ -143,7 +143,7 @@ TEST(Imgcodecs_Tiff, decode_infinite_rowsperstrip)
+     EXPECT_NO_THROW(cv::imread(filename, IMREAD_UNCHANGED));
+-    remove(filename.c_str());
++    EXPECT_EQ(0, remove(filename.c_str()));
+ }
+ //==================================================================================================
+diff --git a/modules/imgcodecs/test/test_webp.cpp b/modules/imgcodecs/test/test_webp.cpp
+index 6d40ce21e2d..d82fdd28964 100644
+--- a/modules/imgcodecs/test/test_webp.cpp
++++ b/modules/imgcodecs/test/test_webp.cpp
+@@ -44,7 +44,7 @@ TEST(Imgcodecs_WebP, encode_decode_lossless_webp)
+         }
+     }
+-    remove(output.c_str());
++    EXPECT_EQ(0, remove(output.c_str()));
+     cv::Mat decode = cv::imdecode(buf, IMREAD_COLOR);
+     ASSERT_FALSE(decode.empty());
+@@ -71,7 +71,7 @@ TEST(Imgcodecs_WebP, encode_decode_lossy_webp)
+         EXPECT_NO_THROW(cv::imwrite(output, img, params));
+         cv::Mat img_webp = cv::imread(output);
+-        remove(output.c_str());
++        EXPECT_EQ(0, remove(output.c_str()));
+         EXPECT_FALSE(img_webp.empty());
+         EXPECT_EQ(3,   img_webp.channels());
+         EXPECT_EQ(512, img_webp.cols);
+@@ -96,7 +96,7 @@ TEST(Imgcodecs_WebP, encode_decode_with_alpha_webp)
+     EXPECT_NO_THROW(cv::imwrite(output, img));
+     cv::Mat img_webp = cv::imread(output);
+-    remove(output.c_str());
++    EXPECT_EQ(0, remove(output.c_str()));
+     EXPECT_FALSE(img_webp.empty());
+     EXPECT_EQ(4,   img_webp.channels());
+     EXPECT_EQ(512, img_webp.cols);
diff --git a/media-libs/opencv/opencv-3.3.0.ebuild b/media-libs/opencv/opencv-3.3.0.ebuild
new file mode 100644 (file)
index 0000000..db01ccd
--- /dev/null
@@ -0,0 +1,354 @@
+# Copyright 1999-2017 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=6
+PYTHON_COMPAT=( python{2_7,3_4,3_5} )
+
+inherit toolchain-funcs python-r1 java-pkg-opt-2 java-ant-2 cmake-multilib
+
+DESCRIPTION="A collection of algorithms and sample code for various computer vision problems"
+HOMEPAGE="http://opencv.org"
+
+SRC_URI="https://github.com/${PN}/${PN}/archive/${PV}.tar.gz -> ${P}.tar.gz
+       contrib? ( https://github.com/${PN}/${PN}_contrib/archive/${PV}.tar.gz -> ${P}_contrib.tar.gz
+               contrib_xfeatures2d? ( https://dev.gentoo.org/~amynka/snap/vgg_boostdesc-3.2.0.tar.gz  ) ) "
+LICENSE="BSD"
+SLOT="0/3.3" # subslot = libopencv* soname version
+KEYWORDS="~amd64 ~arm ~arm64 ~ppc ~ppc64 ~x86 ~amd64-linux"
+IUSE="contrib cuda debug +eigen examples ffmpeg gdal gflags glog gphoto2 gstreamer gtk ieee1394 ipp jpeg jpeg2k lapack libav opencl openexr opengl openmp pch png +python qt5 tesseract testprograms threads tiff vaapi v4l vtk webp xine contrib_cvv contrib_hdf contrib_sfm contrib_xfeatures2d"
+
+# OpenGL needs gtk or Qt installed to activate, otherwise build system
+# will silently disable it without the user knowing, which defeats the
+# purpose of the opengl use flag.
+REQUIRED_USE="
+       cuda? ( tesseract? ( opencl ) )
+       gflags? ( contrib )
+       glog? ( contrib )
+       contrib_cvv? ( contrib qt5 )
+       contrib_hdf? ( contrib )
+       contrib_sfm? ( contrib eigen gflags glog )
+       contrib_xfeatures2d? ( contrib cuda )
+       java? ( python )
+       opengl? ( || ( gtk qt5 ) )
+       python? ( ${PYTHON_REQUIRED_USE} )
+       tesseract? ( contrib )"
+
+# The following logic is intrinsic in the build system, but we do not enforce
+# it on the useflags since this just blocks emerging pointlessly:
+#      gtk? ( !qt5 )
+#      openmp? ( !threads )
+
+RDEPEND="
+       app-arch/bzip2[${MULTILIB_USEDEP}]
+       sys-libs/zlib[${MULTILIB_USEDEP}]
+       cuda? ( dev-util/nvidia-cuda-toolkit:0= )
+       contrib_hdf? ( sci-libs/hdf5 )
+       ffmpeg? (
+               libav? ( media-video/libav:0=[${MULTILIB_USEDEP}] )
+               !libav? ( media-video/ffmpeg:0=[${MULTILIB_USEDEP}] )
+       )
+       gdal? ( sci-libs/gdal:= )
+       gflags? ( dev-cpp/gflags[${MULTILIB_USEDEP}] )
+       glog? ( dev-cpp/glog[${MULTILIB_USEDEP}] )
+       gphoto2? ( media-libs/libgphoto2[${MULTILIB_USEDEP}] )
+       gstreamer? (
+               media-libs/gstreamer:1.0[${MULTILIB_USEDEP}]
+               media-libs/gst-plugins-base:1.0[${MULTILIB_USEDEP}]
+       )
+       gtk? (
+               dev-libs/glib:2[${MULTILIB_USEDEP}]
+               x11-libs/gtk+:2[${MULTILIB_USEDEP}]
+               opengl? ( x11-libs/gtkglext[${MULTILIB_USEDEP}] )
+       )
+       ieee1394? (
+               media-libs/libdc1394[${MULTILIB_USEDEP}]
+               sys-libs/libraw1394[${MULTILIB_USEDEP}]
+       )
+       ipp? ( sci-libs/ipp )
+       java? ( >=virtual/jre-1.6:* )
+       jpeg? ( virtual/jpeg:0[${MULTILIB_USEDEP}] )
+       jpeg2k? ( media-libs/jasper:=[${MULTILIB_USEDEP}] )
+       lapack? ( virtual/lapack )
+       opencl? ( virtual/opencl[${MULTILIB_USEDEP}] )
+       openexr? ( media-libs/openexr[${MULTILIB_USEDEP}] )
+       opengl? (
+               virtual/opengl[${MULTILIB_USEDEP}]
+               virtual/glu[${MULTILIB_USEDEP}]
+       )
+       png? ( media-libs/libpng:0=[${MULTILIB_USEDEP}] )
+       python? ( ${PYTHON_DEPS} dev-python/numpy[${PYTHON_USEDEP}] )
+       qt5? (
+               dev-qt/qtgui:5
+               dev-qt/qtwidgets:5
+               dev-qt/qttest:5
+               dev-qt/qtconcurrent:5
+               opengl? ( dev-qt/qtopengl:5 )
+       )
+       tesseract? ( app-text/tesseract[opencl=] )
+       threads? ( dev-cpp/tbb[${MULTILIB_USEDEP}] )
+       tiff? ( media-libs/tiff:0[${MULTILIB_USEDEP}] )
+       v4l? ( >=media-libs/libv4l-0.8.3[${MULTILIB_USEDEP}] )
+       vtk? ( sci-libs/vtk[rendering] )
+       webp? ( media-libs/libwebp[${MULTILIB_USEDEP}] )
+       xine? ( media-libs/xine-lib )"
+DEPEND="${RDEPEND}
+       virtual/pkgconfig[${MULTILIB_USEDEP}]
+       eigen? ( dev-cpp/eigen:3 )
+       java?  ( >=virtual/jdk-1.6 )"
+
+MULTILIB_WRAPPED_HEADERS=(
+       /usr/include/opencv2/cvconfig.h
+       /usr/include/opencv2/opencv_modules.hpp
+       # [contrib_cvv]
+       /usr/include/opencv2/cvv.hpp
+       /usr/include/opencv2/cvv/call_meta_data.hpp
+       /usr/include/opencv2/cvv/cvv.hpp
+       /usr/include/opencv2/cvv/debug_mode.hpp
+       /usr/include/opencv2/cvv/dmatch.hpp
+       /usr/include/opencv2/cvv/filter.hpp
+       /usr/include/opencv2/cvv/final_show.hpp
+       /usr/include/opencv2/cvv/show_image.hpp
+       # [contrib_hdf]
+       /usr/include/opencv2/hdf.hpp
+       /usr/include/opencv2/hdf/hdf5.hpp
+       # [vtk]
+       /usr/include/opencv2/viz.hpp
+       /usr/include/opencv2/viz/types.hpp
+       /usr/include/opencv2/viz/viz3d.hpp
+       /usr/include/opencv2/viz/vizcore.hpp
+       /usr/include/opencv2/viz/widget_accessor.hpp
+       /usr/include/opencv2/viz/widgets.hpp
+)
+
+PATCHES=(
+       "${FILESDIR}/${PN}-3.0.0-gles.patch"
+       "${FILESDIR}/${PN}-3.1.0-java-magic.patch"
+       "${FILESDIR}/${PN}-3.1.0-find-libraries-fix.patch"
+       "${FILESDIR}/${P}-imgcodecs-gcc.patch" # bug 627958 and https://github.com/opencv/opencv/pull/9376
+)
+
+pkg_pretend() {
+       [[ ${MERGE_TYPE} != binary ]] && use openmp && tc-check-openmp
+}
+
+pkg_setup() {
+       [[ ${MERGE_TYPE} != binary ]] && use openmp && tc-check-openmp
+       java-pkg-opt-2_pkg_setup
+}
+
+src_prepare() {
+       cmake-utils_src_prepare
+
+       # remove bundled stuff
+       rm -rf 3rdparty || die "Removing 3rd party components failed"
+       sed -e '/add_subdirectory(.*3rdparty.*)/ d' \
+               -i CMakeLists.txt cmake/*cmake || die
+
+       if use contrib && use contrib_xfeatures2d; then
+               cd  "${WORKDIR}/${PN}_contrib-${PV}" || die
+               eapply "${FILESDIR}/${P}-contrib-xfeatures2d.patch"
+               mv "${WORKDIR}"/*.i "${WORKDIR}/${PN}_contrib-${PV}"/modules/xfeatures2d/src/ || die
+       fi
+
+       java-pkg-opt-2_src_prepare
+
+       # this really belongs in src_prepare() too
+       JAVA_ANT_ENCODING="iso-8859-1"
+       # set encoding so even this cmake build will pick it up.
+       export ANT_OPTS+=" -Dfile.encoding=iso-8859-1"
+       java-ant-2_src_configure
+}
+
+multilib_src_configure() {
+       # please dont sort here, order is the same as in CMakeLists.txt
+       GLOBALCMAKEARGS=(
+       # Optional 3rd party components
+       # ===================================================
+               -DWITH_1394=$(usex ieee1394)
+       #       -DWITH_AVFOUNDATION=OFF # IOS
+               -DWITH_VTK=$(multilib_native_usex vtk)
+               -DWITH_EIGEN=$(usex eigen)
+               -DWITH_VFW=OFF # Video windows support
+               -DWITH_FFMPEG=$(usex ffmpeg)
+               -DWITH_GSTREAMER=$(usex gstreamer)
+               -DWITH_GSTREAMER_0_10=OFF       # Don't want this
+               -DWITH_GTK=$(usex gtk)
+               -DWITH_GTK_2_X=$(usex gtk)
+               -DWITH_IPP=$(multilib_native_usex ipp)
+               -DWITH_JASPER=$(usex jpeg2k)
+               -DWITH_JPEG=$(usex jpeg)
+               -DWITH_WEBP=$(usex webp)
+               -DWITH_OPENEXR=$(usex openexr)
+               -DWITH_OPENGL=$(usex opengl)
+               -DWITH_OPENVX=OFF
+               -DWITH_OPENNI=OFF       # Not packaged
+               -DWITH_OPENNI2=OFF      # Not packaged
+               -DWITH_PNG=$(usex png)
+               -DWITH_GDCM=OFF
+               -DWITH_PVAPI=OFF
+               -DWITH_GIGEAPI=OFF
+               -DWITH_ARAVIS=OFF
+               -DWITH_QT=$(multilib_native_usex qt5 5 OFF)
+               -DWITH_WIN32UI=OFF              # Windows only
+       #       -DWITH_QUICKTIME=OFF
+       #       -DWITH_QTKIT=OFF
+               -DWITH_TBB=$(usex threads)
+               -DWITH_OPENMP=$(usex openmp)
+               -DWITH_CSTRIPES=OFF
+               -DWITH_PTHREADS_PF=ON
+               -DWITH_TIFF=$(usex tiff)
+               -DWITH_UNICAP=OFF               # Not packaged
+               -DWITH_V4L=$(usex v4l)
+               -DWITH_LIBV4L=$(usex v4l)
+               -DWITH_DSHOW=ON                 # direct show supp
+               -DWITH_MSMF=OFF
+               -DWITH_XIMEA=OFF        # Windows only
+               -DWITH_XINE=$(multilib_native_usex xine)
+               -DWITH_CLP=OFF
+               -DWITH_OPENCL=$(usex opencl)
+               -DWITH_OPENCL_SVM=OFF
+               -DWITH_OPENCLAMDFFT=$(usex opencl)
+               -DWITH_OPENCLAMDBLAS=$(usex opencl)
+               -DWITH_DIRECTX=OFF
+               -DWITH_INTELPERC=OFF
+               -DWITH_JAVA=$(multilib_native_usex java) # Ant needed, no compile flag
+               -DWITH_IPP_A=OFF
+               -DWITH_MATLAB=OFF
+               -DWITH_VA=$(usex vaapi)
+               -DWITH_VA_INTEL=$(usex vaapi)
+               -DWITH_GDAL=$(multilib_native_usex gdal)
+               -DWITH_GPHOTO2=$(usex gphoto2)
+               -DWITH_LAPACK=$(multilib_native_usex lapack)
+               -DWITH_ITT=OFF # 3dparty libs itt_notify
+       # ===================================================
+       # CUDA build components: nvidia-cuda-toolkit takes care of GCC version
+       # ===================================================
+               -DWITH_CUDA=$(multilib_native_usex cuda)
+               -DWITH_CUBLAS=$(multilib_native_usex cuda)
+               -DWITH_CUFFT=$(multilib_native_usex cuda)
+               -DWITH_NVCUVID=OFF
+#              -DWITH_NVCUVID=$(usex cuda)
+               -DCUDA_NPP_LIBRARY_ROOT_DIR=$(usex cuda "${EPREFIX}/opt/cuda" "")
+       # ===================================================
+       # OpenCV build components
+       # ===================================================
+               -DBUILD_SHARED_LIBS=ON
+               -DBUILD_ANDROID_EXAMPLES=OFF
+               -BUILD_opencv_apps=
+               -DBUILD_DOCS=OFF # Doesn't install anyways.
+               -DBUILD_EXAMPLES=$(multilib_native_usex examples)
+               -DBUILD_PERF_TESTS=OFF
+               -DBUILD_TESTS=$(multilib_native_usex testprograms)
+               -DBUILD_WITH_DEBUG_INFO=$(usex debug)
+       #       -DBUILD_WITH_STATIC_CRT=OFF
+               -DBUILD_WITH_DYNAMIC_IPP=OFF
+               -DBUILD_FAT_JAVA_LIB=$(multilib_native_usex java)
+       #       -DBUILD_ANDROID_SERVICE=OFF
+               -DBUILD_CUDA_STUBS=$(multilib_native_usex cuda)
+               -DOPENCV_EXTRA_MODULES_PATH=$(usex contrib "${WORKDIR}/opencv_contrib-${PV}/modules" "")
+       # ===================================================
+       # OpenCV installation options
+       # ===================================================
+               -DINSTALL_CREATE_DISTRIB=OFF
+               -DINSTALL_C_EXAMPLES=$(multilib_native_usex examples)
+               -DINSTALL_TESTS=$(multilib_native_usex testprograms)
+               -DINSTALL_PYTHON_EXAMPLES=$(multilib_native_usex examples)
+       #       -DINSTALL_ANDROID_EXAMPLES=OFF
+               -DINSTALL_TO_MANGLED_PATHS=OFF
+       # ===================================================
+       # OpenCV build options
+       # ===================================================
+               -DENABLE_CCACHE=OFF
+               -DENABLE_PRECOMPILED_HEADERS=$(usex pch)
+               -DENABLE_SOLUTION_FOLDERS=OFF
+               -DENABLE_PROFILING=OFF
+               -DENABLE_COVERAGE=OFF
+
+               -DHAVE_opencv_java=$(multilib_native_usex java YES NO)
+               -DENABLE_NOISY_WARNINGS=OFF
+               -DOPENCV_WARNINGS_ARE_ERRORS=OFF
+               -DENABLE_IMPL_COLLECTION=OFF
+               -DENABLE_INSTRUMENTATION=OFF
+               -DGENERATE_ABI_DESCRIPTOR=OFF
+               -DDOWNLOAD_EXTERNAL_TEST_DATA=OFF
+       # ===================================================
+       # things we want to be hard off or not yet figured out
+       # ===================================================
+               -DBUILD_PACKAGE=OFF
+       # ===================================================
+       # things we want to be hard enabled not worth useflag
+       # ===================================================
+               -DCMAKE_SKIP_RPATH=ON
+               -DOPENCV_DOC_INSTALL_PATH=
+       )
+
+       # ===================================================
+       # OpenCV Contrib Modules
+       # ===================================================
+       if use contrib; then
+               GLOBALCMAKEARGS+=(
+                       -DBUILD_opencv_dnn=OFF
+                       -DBUILD_opencv_dnns_easily_fooled=OFF
+                       -DBUILD_opencv_xfeatures2d=$(usex contrib_xfeatures2d ON OFF)
+                       -DBUILD_opencv_cvv=$(usex contrib_cvv ON OFF)
+                       -DBUILD_opencv_hdf=$(multilib_native_usex contrib_hdf ON OFF)
+                       -DBUILD_opencv_sfm=$(usex contrib_sfm ON OFF)
+               )
+
+               if multilib_is_native_abi; then
+                       GLOBALCMAKEARGS+=(
+                               -DCMAKE_DISABLE_FIND_PACKAGE_Tesseract=$(usex !tesseract)
+                       )
+               else
+                       GLOBALCMAKEARGS+=(
+                               -DCMAKE_DISABLE_FIND_PACKAGE_Tesseract=ON
+                       )
+               fi
+       fi
+
+       # workaround for bug 413429
+       tc-export CC CXX
+
+       local mycmakeargs=( ${GLOBALCMAKEARGS[@]}
+               -DPYTHON_EXECUTABLE=OFF
+               -DINSTALL_PYTHON_EXAMPLES=OFF
+       )
+
+       cmake-utils_src_configure
+}
+
+python_module_compile() {
+       local BUILD_DIR=${orig_BUILD_DIR}
+       local mycmakeargs=( ${GLOBALCMAKEARGS[@]} )
+
+       # Set all python variables to load the correct Gentoo paths
+       mycmakeargs+=(
+               # cheap trick: python_setup sets one of them as a symlink
+               # to the correct interpreter, and the other to fail-wrapper
+               -DPYTHON2_EXECUTABLE=$(type -P python2)
+               -DPYTHON3_EXECUTABLE=$(type -P python3)
+               -DINSTALL_PYTHON_EXAMPLES=$(usex examples)
+       )
+
+       # Regenerate cache file. Can't use rebuild_cache as it won't
+       # have the Gentoo specific options.
+       rm -rf CMakeCache.txt || die "rm failed"
+       cmake-utils_src_configure
+       cmake-utils_src_compile
+       cmake-utils_src_install
+
+       # Remove compiled binary so new version compiles
+       # Avoid conflicts with new module builds as build system doesn't
+       # really support it.
+       rm -rf modules/python2 || die "rm failed"
+}
+
+multilib_src_install() {
+       cmake-utils_src_install
+
+       # Build and install the python modules for all targets
+       if multilib_is_native_abi && use python; then
+               local orig_BUILD_DIR=${BUILD_DIR}
+               python_foreach_impl python_module_compile
+       fi
+}