summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeetika Singh <Neetika.Singh@kpit.com>2021-03-09 16:53:36 +0530
committerArmin Kuster <akuster808@gmail.com>2021-03-16 08:40:07 -0700
commit389757a7494221fea1d8437e9a01c6e4fb4700af (patch)
treea5ba4856aeb7ae62a7dc4b3300902bb81fc6923c
parent1ad4455f2830c408f9c2e7a4b094c5e555db0cf2 (diff)
downloadmeta-openembedded-389757a7494221fea1d8437e9a01c6e4fb4700af.tar.gz
opencv: Security fixes
Added patches to fix below CVE's: 1. CVE-2019-14491, CVE-2019-14492 Link: https://github.com/opencv/opencv/commit/ac425f67e4c1d0da9afb9203f0918d8d57c067ed 2. CVE-2019-14493 Link: https://github.com/opencv/opencv/commit/5691d998ead1d9b0542bcfced36c2dceb3a59023 3. CVE-2019-15939 Link: https://github.com/opencv/opencv/commit/5a497077f109d543ab86dfdf8add1c76c0e47d29 4. CVE-2019-19624 Link: https://github.com/opencv/opencv/commit/d1615ba11a93062b1429fce9f0f638d1572d3418 Signed-off-by: Neetika.Singh <Neetika.Singh@kpit.com> Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r--meta-oe/recipes-support/opencv/opencv/CVE-2019-14491.patch148
-rw-r--r--meta-oe/recipes-support/opencv/opencv/CVE-2019-14493.patch237
-rw-r--r--meta-oe/recipes-support/opencv/opencv/CVE-2019-15939.patch73
-rw-r--r--meta-oe/recipes-support/opencv/opencv/CVE-2019-19624.patch157
-rw-r--r--meta-oe/recipes-support/opencv/opencv_4.1.0.bb4
5 files changed, 619 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/opencv/opencv/CVE-2019-14491.patch b/meta-oe/recipes-support/opencv/opencv/CVE-2019-14491.patch
new file mode 100644
index 000000000..656000a8e
--- /dev/null
+++ b/meta-oe/recipes-support/opencv/opencv/CVE-2019-14491.patch
@@ -0,0 +1,148 @@
1From 321c74ccd6077bdea1d47450ca4fe955cb5b6330 Mon Sep 17 00:00:00 2001
2From: Alexander Alekhin <alexander.alekhin@intel.com>
3Date: Thu, 25 Jul 2019 17:15:59 +0300
4Subject: [PATCH] objdetect: validate feature rectangle on reading
5
6CVE: CVE-2019-14491
7CVE: CVE-2019-14492
8Upstream-Status: Backport [https://github.com/opencv/opencv/commit/ac425f67e4c1d0da9afb9203f0918d8d57c067ed.patch]
9Comment: No changes in any hunk
10
11Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
12---
13 modules/objdetect/src/cascadedetect.cpp | 43 +++++++++++++++++++++----
14 modules/objdetect/src/cascadedetect.hpp | 6 ++--
15 2 files changed, 40 insertions(+), 9 deletions(-)
16
17diff --git a/modules/objdetect/src/cascadedetect.cpp b/modules/objdetect/src/cascadedetect.cpp
18index 4b2078306fe..bd62cd21a1b 100644
19--- a/modules/objdetect/src/cascadedetect.cpp
20+++ b/modules/objdetect/src/cascadedetect.cpp
21@@ -47,6 +47,10 @@
22 #include "opencv2/objdetect/objdetect_c.h"
23 #include "opencl_kernels_objdetect.hpp"
24
25+#if defined(_MSC_VER)
26+# pragma warning(disable:4458) // declaration of 'origWinSize' hides class member
27+#endif
28+
29 namespace cv
30 {
31
32@@ -537,7 +541,7 @@ bool FeatureEvaluator::setImage( InputArray _image, const std::vector<float>& _s
33
34 //---------------------------------------------- HaarEvaluator ---------------------------------------
35
36-bool HaarEvaluator::Feature :: read( const FileNode& node )
37+bool HaarEvaluator::Feature::read(const FileNode& node, const Size& origWinSize)
38 {
39 FileNode rnode = node[CC_RECTS];
40 FileNodeIterator it = rnode.begin(), it_end = rnode.end();
41@@ -549,11 +553,23 @@ bool HaarEvaluator::Feature :: read( const FileNode& node )
42 rect[ri].weight = 0.f;
43 }
44
45+ const int W = origWinSize.width;
46+ const int H = origWinSize.height;
47+
48 for(ri = 0; it != it_end; ++it, ri++)
49 {
50 FileNodeIterator it2 = (*it).begin();
51- it2 >> rect[ri].r.x >> rect[ri].r.y >>
52- rect[ri].r.width >> rect[ri].r.height >> rect[ri].weight;
53+ Feature::RectWeigth& rw = rect[ri];
54+ it2 >> rw.r.x >> rw.r.y >> rw.r.width >> rw.r.height >> rw.weight;
55+ // input validation
56+ {
57+ CV_CheckGE(rw.r.x, 0, "Invalid HAAR feature");
58+ CV_CheckGE(rw.r.y, 0, "Invalid HAAR feature");
59+ CV_CheckLT(rw.r.x, W, "Invalid HAAR feature"); // necessary for overflow checks
60+ CV_CheckLT(rw.r.y, H, "Invalid HAAR feature"); // necessary for overflow checks
61+ CV_CheckLE(rw.r.x + rw.r.width, W, "Invalid HAAR feature");
62+ CV_CheckLE(rw.r.y + rw.r.height, H, "Invalid HAAR feature");
63+ }
64 }
65
66 tilted = (int)node[CC_TILTED] != 0;
67@@ -598,7 +614,7 @@ bool HaarEvaluator::read(const FileNode& node, Size _origWinSize)
68
69 for(i = 0; i < n; i++, ++it)
70 {
71- if(!ff[i].read(*it))
72+ if(!ff[i].read(*it, _origWinSize))
73 return false;
74 if( ff[i].tilted )
75 hasTiltedFeatures = true;
76@@ -759,11 +775,24 @@ int HaarEvaluator::getSquaresOffset() const
77 }
78
79 //---------------------------------------------- LBPEvaluator -------------------------------------
80-bool LBPEvaluator::Feature :: read(const FileNode& node )
81+bool LBPEvaluator::Feature::read(const FileNode& node, const Size& origWinSize)
82 {
83 FileNode rnode = node[CC_RECT];
84 FileNodeIterator it = rnode.begin();
85 it >> rect.x >> rect.y >> rect.width >> rect.height;
86+
87+ const int W = origWinSize.width;
88+ const int H = origWinSize.height;
89+ // input validation
90+ {
91+ CV_CheckGE(rect.x, 0, "Invalid LBP feature");
92+ CV_CheckGE(rect.y, 0, "Invalid LBP feature");
93+ CV_CheckLT(rect.x, W, "Invalid LBP feature");
94+ CV_CheckLT(rect.y, H, "Invalid LBP feature");
95+ CV_CheckLE(rect.x + rect.width, W, "Invalid LBP feature");
96+ CV_CheckLE(rect.y + rect.height, H, "Invalid LBP feature");
97+ }
98+
99 return true;
100 }
101
102@@ -797,7 +826,7 @@ bool LBPEvaluator::read( const FileNode& node, Size _origWinSize )
103 std::vector<Feature>& ff = *features;
104 for(int i = 0; it != it_end; ++it, i++)
105 {
106- if(!ff[i].read(*it))
107+ if(!ff[i].read(*it, _origWinSize))
108 return false;
109 }
110 nchannels = 1;
111@@ -1477,6 +1506,8 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root)
112 origWinSize.width = (int)root[CC_WIDTH];
113 origWinSize.height = (int)root[CC_HEIGHT];
114 CV_Assert( origWinSize.height > 0 && origWinSize.width > 0 );
115+ CV_CheckLE(origWinSize.width, 1000000, "Invalid window size (too large)");
116+ CV_CheckLE(origWinSize.height, 1000000, "Invalid window size (too large)");
117
118 // load feature params
119 FileNode fn = root[CC_FEATURE_PARAMS];
120diff --git a/modules/objdetect/src/cascadedetect.hpp b/modules/objdetect/src/cascadedetect.hpp
121index f9910530b94..d9a288fcdda 100644
122--- a/modules/objdetect/src/cascadedetect.hpp
123+++ b/modules/objdetect/src/cascadedetect.hpp
124@@ -317,12 +317,12 @@ class HaarEvaluator CV_FINAL : public FeatureEvaluator
125 struct Feature
126 {
127 Feature();
128- bool read( const FileNode& node );
129+ bool read(const FileNode& node, const Size& origWinSize);
130
131 bool tilted;
132
133 enum { RECT_NUM = 3 };
134- struct
135+ struct RectWeigth
136 {
137 Rect r;
138 float weight;
139@@ -412,7 +412,7 @@ class LBPEvaluator CV_FINAL : public FeatureEvaluator
140 Feature( int x, int y, int _block_w, int _block_h ) :
141 rect(x, y, _block_w, _block_h) {}
142
143- bool read(const FileNode& node );
144+ bool read(const FileNode& node, const Size& origWinSize);
145
146 Rect rect; // weight and height for block
147 };
148
diff --git a/meta-oe/recipes-support/opencv/opencv/CVE-2019-14493.patch b/meta-oe/recipes-support/opencv/opencv/CVE-2019-14493.patch
new file mode 100644
index 000000000..2b5e06f23
--- /dev/null
+++ b/meta-oe/recipes-support/opencv/opencv/CVE-2019-14493.patch
@@ -0,0 +1,237 @@
1From 5691d998ead1d9b0542bcfced36c2dceb3a59023 Mon Sep 17 00:00:00 2001
2From: Alexander Alekhin <alexander.alekhin@intel.com>
3Date: Thu, 25 Jul 2019 15:14:22 +0300
4Subject: [PATCH] core(persistence): added null ptr checks
5
6CVE: CVE-2019-14493
7Upstream-Status: Backport [https://github.com/opencv/opencv/commit/5691d998ead1d9b0542bcfced36c2dceb3a59023.patch]
8Comment: No changes in any hunk
9
10Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
11---
12 modules/core/src/persistence_json.cpp | 12 ++++++++++++
13 modules/core/src/persistence_xml.cpp | 21 +++++++++++++++++++++
14 modules/core/src/persistence_yml.cpp | 21 +++++++++++++++++++++
15 3 files changed, 54 insertions(+)
16
17diff --git a/modules/core/src/persistence_json.cpp b/modules/core/src/persistence_json.cpp
18index ae678e1b8b1..89914e6534f 100644
19--- a/modules/core/src/persistence_json.cpp
20+++ b/modules/core/src/persistence_json.cpp
21@@ -296,6 +296,8 @@ class JSONParser : public FileStorageParser
22
23 while ( is_eof == false && is_completed == false )
24 {
25+ if (!ptr)
26+ CV_PARSE_ERROR_CPP("Invalid input");
27 switch ( *ptr )
28 {
29 /* comment */
30@@ -381,6 +383,7 @@ class JSONParser : public FileStorageParser
31 if ( is_eof || !is_completed )
32 {
33 ptr = fs->bufferStart();
34+ CV_Assert(ptr);
35 *ptr = '\0';
36 fs->setEof();
37 if( !is_completed )
38@@ -392,6 +395,9 @@ class JSONParser : public FileStorageParser
39
40 char* parseKey( char* ptr, FileNode& collection, FileNode& value_placeholder )
41 {
42+ if (!ptr)
43+ CV_PARSE_ERROR_CPP("Invalid input");
44+
45 if( *ptr != '"' )
46 CV_PARSE_ERROR_CPP( "Key must start with \'\"\'" );
47
48@@ -430,6 +436,9 @@ class JSONParser : public FileStorageParser
49
50 char* parseValue( char* ptr, FileNode& node )
51 {
52+ if (!ptr)
53+ CV_PARSE_ERROR_CPP("Invalid value input");
54+
55 ptr = skipSpaces( ptr );
56 if( !ptr || !*ptr )
57 CV_PARSE_ERROR_CPP( "Unexpected End-Of-File" );
58@@ -817,6 +826,9 @@ class JSONParser : public FileStorageParser
59
60 bool parse( char* ptr )
61 {
62+ if (!ptr)
63+ CV_PARSE_ERROR_CPP("Invalid input");
64+
65 ptr = skipSpaces( ptr );
66 if ( !ptr || !*ptr )
67 return false;
68diff --git a/modules/core/src/persistence_xml.cpp b/modules/core/src/persistence_xml.cpp
69index fb30d90896e..89876dd3da8 100644
70--- a/modules/core/src/persistence_xml.cpp
71+++ b/modules/core/src/persistence_xml.cpp
72@@ -360,6 +360,9 @@ class XMLParser : public FileStorageParser
73
74 char* skipSpaces( char* ptr, int mode )
75 {
76+ if (!ptr)
77+ CV_PARSE_ERROR_CPP("Invalid input");
78+
79 int level = 0;
80
81 for(;;)
82@@ -441,6 +444,9 @@ class XMLParser : public FileStorageParser
83
84 char* parseValue( char* ptr, FileNode& node )
85 {
86+ if (!ptr)
87+ CV_PARSE_ERROR_CPP("Invalid input");
88+
89 FileNode new_elem;
90 bool have_space = true;
91 int value_type = node.type();
92@@ -456,6 +462,8 @@ class XMLParser : public FileStorageParser
93 (c == '<' && ptr[1] == '!' && ptr[2] == '-') )
94 {
95 ptr = skipSpaces( ptr, 0 );
96+ if (!ptr)
97+ CV_PARSE_ERROR_CPP("Invalid input");
98 have_space = true;
99 c = *ptr;
100 }
101@@ -502,6 +510,8 @@ class XMLParser : public FileStorageParser
102 {
103 ptr = fs->parseBase64( ptr, 0, new_elem);
104 ptr = skipSpaces( ptr, 0 );
105+ if (!ptr)
106+ CV_PARSE_ERROR_CPP("Invalid input");
107 }
108
109 ptr = parseTag( ptr, key2, type_name, tag_type );
110@@ -645,6 +655,9 @@ class XMLParser : public FileStorageParser
111 char* parseTag( char* ptr, std::string& tag_name,
112 std::string& type_name, int& tag_type )
113 {
114+ if (!ptr)
115+ CV_PARSE_ERROR_CPP("Invalid tag input");
116+
117 if( *ptr == '\0' )
118 CV_PARSE_ERROR_CPP( "Unexpected end of the stream" );
119
120@@ -702,6 +715,8 @@ class XMLParser : public FileStorageParser
121 if( *ptr != '=' )
122 {
123 ptr = skipSpaces( ptr, CV_XML_INSIDE_TAG );
124+ if (!ptr)
125+ CV_PARSE_ERROR_CPP("Invalid attribute");
126 if( *ptr != '=' )
127 CV_PARSE_ERROR_CPP( "Attribute name should be followed by \'=\'" );
128 }
129@@ -740,6 +755,8 @@ class XMLParser : public FileStorageParser
130 if( c != '>' )
131 {
132 ptr = skipSpaces( ptr, CV_XML_INSIDE_TAG );
133+ if (!ptr)
134+ CV_PARSE_ERROR_CPP("Invalid input");
135 c = *ptr;
136 }
137
138@@ -781,6 +798,8 @@ class XMLParser : public FileStorageParser
139
140 // CV_XML_INSIDE_TAG is used to prohibit leading comments
141 ptr = skipSpaces( ptr, CV_XML_INSIDE_TAG );
142+ if (!ptr)
143+ CV_PARSE_ERROR_CPP("Invalid input");
144
145 if( memcmp( ptr, "<?xml", 5 ) != 0 ) // FIXIT ptr[1..] - out of bounds read without check
146 CV_PARSE_ERROR_CPP( "Valid XML should start with \'<?xml ...?>\'" );
147@@ -791,6 +810,8 @@ class XMLParser : public FileStorageParser
148 while( ptr && *ptr != '\0' )
149 {
150 ptr = skipSpaces( ptr, 0 );
151+ if (!ptr)
152+ CV_PARSE_ERROR_CPP("Invalid input");
153
154 if( *ptr != '\0' )
155 {
156diff --git a/modules/core/src/persistence_yml.cpp b/modules/core/src/persistence_yml.cpp
157index 4129ca1dc57..7742e827701 100644
158--- a/modules/core/src/persistence_yml.cpp
159+++ b/modules/core/src/persistence_yml.cpp
160@@ -330,6 +330,9 @@ class YAMLParser : public FileStorageParser
161
162 char* skipSpaces( char* ptr, int min_indent, int max_comment_indent )
163 {
164+ if (!ptr)
165+ CV_PARSE_ERROR_CPP("Invalid input");
166+
167 for(;;)
168 {
169 while( *ptr == ' ' )
170@@ -374,6 +377,9 @@ class YAMLParser : public FileStorageParser
171
172 bool getBase64Row(char* ptr, int indent, char* &beg, char* &end)
173 {
174+ if (!ptr)
175+ CV_PARSE_ERROR_CPP("Invalid input");
176+
177 beg = end = ptr = skipSpaces(ptr, 0, INT_MAX);
178 if (!ptr || !*ptr)
179 return false; // end of file
180@@ -394,6 +400,9 @@ class YAMLParser : public FileStorageParser
181
182 char* parseKey( char* ptr, FileNode& map_node, FileNode& value_placeholder )
183 {
184+ if (!ptr)
185+ CV_PARSE_ERROR_CPP("Invalid input");
186+
187 char c;
188 char *endptr = ptr - 1, *saveptr;
189
190@@ -422,6 +431,9 @@ class YAMLParser : public FileStorageParser
191
192 char* parseValue( char* ptr, FileNode& node, int min_indent, bool is_parent_flow )
193 {
194+ if (!ptr)
195+ CV_PARSE_ERROR_CPP("Invalid input");
196+
197 char* endptr = 0;
198 char c = ptr[0], d = ptr[1];
199 int value_type = FileNode::NONE;
200@@ -508,6 +520,8 @@ class YAMLParser : public FileStorageParser
201
202 *endptr = d;
203 ptr = skipSpaces( endptr, min_indent, INT_MAX );
204+ if (!ptr)
205+ CV_PARSE_ERROR_CPP("Invalid input");
206
207 c = *ptr;
208
209@@ -634,6 +648,8 @@ class YAMLParser : public FileStorageParser
210 FileNode elem;
211
212 ptr = skipSpaces( ptr, new_min_indent, INT_MAX );
213+ if (!ptr)
214+ CV_PARSE_ERROR_CPP("Invalid input");
215 if( *ptr == '}' || *ptr == ']' )
216 {
217 if( *ptr != d )
218@@ -647,6 +663,8 @@ class YAMLParser : public FileStorageParser
219 if( *ptr != ',' )
220 CV_PARSE_ERROR_CPP( "Missing , between the elements" );
221 ptr = skipSpaces( ptr + 1, new_min_indent, INT_MAX );
222+ if (!ptr)
223+ CV_PARSE_ERROR_CPP("Invalid input");
224 }
225
226 if( struct_type == FileNode::MAP )
227@@ -746,6 +764,9 @@ class YAMLParser : public FileStorageParser
228
229 bool parse( char* ptr )
230 {
231+ if (!ptr)
232+ CV_PARSE_ERROR_CPP("Invalid input");
233+
234 bool first = true;
235 bool ok = true;
236 FileNode root_collection(fs->getFS(), 0, 0);
237
diff --git a/meta-oe/recipes-support/opencv/opencv/CVE-2019-15939.patch b/meta-oe/recipes-support/opencv/opencv/CVE-2019-15939.patch
new file mode 100644
index 000000000..e9f8514cb
--- /dev/null
+++ b/meta-oe/recipes-support/opencv/opencv/CVE-2019-15939.patch
@@ -0,0 +1,73 @@
1From 5a497077f109d543ab86dfdf8add1c76c0e47d29 Mon Sep 17 00:00:00 2001
2From: Alexander Alekhin <alexander.alekhin@intel.com>
3Date: Fri, 23 Aug 2019 16:14:53 +0300
4Subject: [PATCH] objdetect: add input check in HOG detector
5
6CVE: CVE-2019-15939
7Upstream-Status: Backport [https://github.com/opencv/opencv/commit/5a497077f109d543ab86dfdf8add1c76c0e47d29.patch]
8Comment: No changes in any hunk
9
10Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
11---
12 modules/objdetect/src/hog.cpp | 19 ++++++++++++-------
13 1 file changed, 12 insertions(+), 7 deletions(-)
14
15diff --git a/modules/objdetect/src/hog.cpp b/modules/objdetect/src/hog.cpp
16index 9524851eebb..378bab30876 100644
17--- a/modules/objdetect/src/hog.cpp
18+++ b/modules/objdetect/src/hog.cpp
19@@ -68,6 +68,7 @@ enum {DESCR_FORMAT_COL_BY_COL, DESCR_FORMAT_ROW_BY_ROW};
20
21 static int numPartsWithin(int size, int part_size, int stride)
22 {
23+ CV_Assert(stride != 0);
24 return (size - part_size + stride) / stride;
25 }
26
27@@ -80,13 +81,17 @@ static Size numPartsWithin(cv::Size size, cv::Size part_size,
28
29 static size_t getBlockHistogramSize(Size block_size, Size cell_size, int nbins)
30 {
31+ CV_Assert(!cell_size.empty());
32 Size cells_per_block = Size(block_size.width / cell_size.width,
33- block_size.height / cell_size.height);
34+ block_size.height / cell_size.height);
35 return (size_t)(nbins * cells_per_block.area());
36 }
37
38 size_t HOGDescriptor::getDescriptorSize() const
39 {
40+ CV_Assert(!cellSize.empty());
41+ CV_Assert(!blockStride.empty());
42+
43 CV_Assert(blockSize.width % cellSize.width == 0 &&
44 blockSize.height % cellSize.height == 0);
45 CV_Assert((winSize.width - blockSize.width) % blockStride.width == 0 &&
46@@ -144,20 +149,20 @@ bool HOGDescriptor::read(FileNode& obj)
47 if( !obj.isMap() )
48 return false;
49 FileNodeIterator it = obj["winSize"].begin();
50- it >> winSize.width >> winSize.height;
51+ it >> winSize.width >> winSize.height; CV_Assert(!winSize.empty());
52 it = obj["blockSize"].begin();
53- it >> blockSize.width >> blockSize.height;
54+ it >> blockSize.width >> blockSize.height; CV_Assert(!blockSize.empty());
55 it = obj["blockStride"].begin();
56- it >> blockStride.width >> blockStride.height;
57+ it >> blockStride.width >> blockStride.height; CV_Assert(!blockStride.empty());
58 it = obj["cellSize"].begin();
59- it >> cellSize.width >> cellSize.height;
60- obj["nbins"] >> nbins;
61+ it >> cellSize.width >> cellSize.height; CV_Assert(!cellSize.empty());
62+ obj["nbins"] >> nbins; CV_Assert(nbins > 0);
63 obj["derivAperture"] >> derivAperture;
64 obj["winSigma"] >> winSigma;
65 obj["histogramNormType"] >> histogramNormType;
66 obj["L2HysThreshold"] >> L2HysThreshold;
67 obj["gammaCorrection"] >> gammaCorrection;
68- obj["nlevels"] >> nlevels;
69+ obj["nlevels"] >> nlevels; CV_Assert(nlevels > 0);
70 if (obj["signedGradient"].empty())
71 signedGradient = false;
72 else
73
diff --git a/meta-oe/recipes-support/opencv/opencv/CVE-2019-19624.patch b/meta-oe/recipes-support/opencv/opencv/CVE-2019-19624.patch
new file mode 100644
index 000000000..79f8514bd
--- /dev/null
+++ b/meta-oe/recipes-support/opencv/opencv/CVE-2019-19624.patch
@@ -0,0 +1,157 @@
1From d1615ba11a93062b1429fce9f0f638d1572d3418 Mon Sep 17 00:00:00 2001
2From: Thang Tran <TranKimThang279@gmail.com>
3Date: Mon, 27 May 2019 08:18:26 +0200
4Subject: [PATCH] video:fixed DISOpticalFlow segfault from small img
5
6CVE: CVE-2019-19624
7Upstream-Status: Backport [https://github.com/opencv/opencv/commit/d1615ba11a93062b1429fce9f0f638d1572d3418.patch]
8Comment: No changes in any hunk
9
10Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
11---
12 modules/video/src/dis_flow.cpp | 67 ++++++++++++++++++++++++-
13 modules/video/test/test_OF_accuracy.cpp | 28 +++++++++++
14 2 files changed, 93 insertions(+), 2 deletions(-)
15
16diff --git a/modules/video/src/dis_flow.cpp b/modules/video/src/dis_flow.cpp
17index a453d8b2b51..806d6f1ddaf 100644
18--- a/modules/video/src/dis_flow.cpp
19+++ b/modules/video/src/dis_flow.cpp
20@@ -140,6 +140,8 @@ class DISOpticalFlowImpl CV_FINAL : public DISOpticalFlow
21 void prepareBuffers(Mat &I0, Mat &I1, Mat &flow, bool use_flow);
22 void precomputeStructureTensor(Mat &dst_I0xx, Mat &dst_I0yy, Mat &dst_I0xy, Mat &dst_I0x, Mat &dst_I0y, Mat &I0x,
23 Mat &I0y);
24+ int autoSelectCoarsestScale(int img_width);
25+ void autoSelectPatchSizeAndScales(int img_width);
26
27 struct PatchInverseSearch_ParBody : public ParallelLoopBody
28 {
29@@ -435,6 +437,44 @@ void DISOpticalFlowImpl::precomputeStructureTensor(Mat &dst_I0xx, Mat &dst_I0yy,
30 }
31 }
32
33+int DISOpticalFlowImpl::autoSelectCoarsestScale(int img_width)
34+{
35+ const int fratio = 5;
36+ return std::max(0, (int)std::floor(log2((2.0f*(float)img_width) / ((float)fratio * (float)patch_size))));
37+}
38+
39+void DISOpticalFlowImpl::autoSelectPatchSizeAndScales(int img_width)
40+{
41+ switch (finest_scale)
42+ {
43+ case 1:
44+ patch_size = 8;
45+ coarsest_scale = autoSelectCoarsestScale(img_width);
46+ finest_scale = std::max(coarsest_scale-2, 0);
47+ break;
48+
49+ case 3:
50+ patch_size = 12;
51+ coarsest_scale = autoSelectCoarsestScale(img_width);
52+ finest_scale = std::max(coarsest_scale-4, 0);
53+ break;
54+
55+ case 4:
56+ patch_size = 12;
57+ coarsest_scale = autoSelectCoarsestScale(img_width);
58+ finest_scale = std::max(coarsest_scale-5, 0);
59+ break;
60+
61+ // default case, fall-through.
62+ case 2:
63+ default:
64+ patch_size = 8;
65+ coarsest_scale = autoSelectCoarsestScale(img_width);
66+ finest_scale = std::max(coarsest_scale-2, 0);
67+ break;
68+ }
69+}
70+
71 DISOpticalFlowImpl::PatchInverseSearch_ParBody::PatchInverseSearch_ParBody(DISOpticalFlowImpl &_dis, int _nstripes,
72 int _hs, Mat &dst_Sx, Mat &dst_Sy,
73 Mat &src_Ux, Mat &src_Uy, Mat &_I0, Mat &_I1,
74@@ -1318,9 +1358,20 @@ bool DISOpticalFlowImpl::ocl_calc(InputArray I0, InputArray I1, InputOutputArray
75 else
76 flow.create(I1Mat.size(), CV_32FC2);
77 UMat &u_flowMat = flow.getUMatRef();
78- coarsest_scale = min((int)(log(max(I0Mat.cols, I0Mat.rows) / (4.0 * patch_size)) / log(2.0) + 0.5), /* Original code serach for maximal movement of width/4 */
79+ coarsest_scale = min((int)(log(max(I0Mat.cols, I0Mat.rows) / (4.0 * patch_size)) / log(2.0) + 0.5), /* Original code search for maximal movement of width/4 */
80 (int)(log(min(I0Mat.cols, I0Mat.rows) / patch_size) / log(2.0))); /* Deepest pyramid level greater or equal than patch*/
81
82+ if (coarsest_scale<0)
83+ CV_Error(cv::Error::StsBadSize, "The input image must have either width or height >= 12");
84+
85+ if (coarsest_scale<finest_scale)
86+ {
87+ // choose the finest level based on coarsest level.
88+ // Refs: https://github.com/tikroeger/OF_DIS/blob/2c9f2a674f3128d3a41c10e41cc9f3a35bb1b523/run_dense.cpp#L239
89+ int original_img_width = I0.size().width;
90+ autoSelectPatchSizeAndScales(original_img_width);
91+ }
92+
93 ocl_prepareBuffers(I0Mat, I1Mat, u_flowMat, use_input_flow);
94 u_Ux[coarsest_scale].setTo(0.0f);
95 u_Uy[coarsest_scale].setTo(0.0f);
96@@ -1385,8 +1436,20 @@ void DISOpticalFlowImpl::calc(InputArray I0, InputArray I1, InputOutputArray flo
97 else
98 flow.create(I1Mat.size(), CV_32FC2);
99 Mat flowMat = flow.getMat();
100- coarsest_scale = min((int)(log(max(I0Mat.cols, I0Mat.rows) / (4.0 * patch_size)) / log(2.0) + 0.5), /* Original code serach for maximal movement of width/4 */
101+ coarsest_scale = min((int)(log(max(I0Mat.cols, I0Mat.rows) / (4.0 * patch_size)) / log(2.0) + 0.5), /* Original code search for maximal movement of width/4 */
102 (int)(log(min(I0Mat.cols, I0Mat.rows) / patch_size) / log(2.0))); /* Deepest pyramid level greater or equal than patch*/
103+
104+ if (coarsest_scale<0)
105+ CV_Error(cv::Error::StsBadSize, "The input image must have either width or height >= 12");
106+
107+ if (coarsest_scale<finest_scale)
108+ {
109+ // choose the finest level based on coarsest level.
110+ // Refs: https://github.com/tikroeger/OF_DIS/blob/2c9f2a674f3128d3a41c10e41cc9f3a35bb1b523/run_dense.cpp#L239
111+ int original_img_width = I0.size().width;
112+ autoSelectPatchSizeAndScales(original_img_width);
113+ }
114+
115 int num_stripes = getNumThreads();
116
117 prepareBuffers(I0Mat, I1Mat, flowMat, use_input_flow);
118diff --git a/modules/video/test/test_OF_accuracy.cpp b/modules/video/test/test_OF_accuracy.cpp
119index affbab65866..b99ffce2a8b 100644
120--- a/modules/video/test/test_OF_accuracy.cpp
121+++ b/modules/video/test/test_OF_accuracy.cpp
122@@ -121,6 +121,34 @@ TEST(DenseOpticalFlow_DIS, ReferenceAccuracy)
123 }
124 }
125
126+TEST(DenseOpticalFlow_DIS, InvalidImgSize_CoarsestLevelLessThanZero)
127+{
128+ cv::Ptr<cv::DISOpticalFlow> of = cv::DISOpticalFlow::create();
129+ const int mat_size = 10;
130+
131+ cv::Mat x(mat_size, mat_size, CV_8UC1, 42);
132+ cv::Mat y(mat_size, mat_size, CV_8UC1, 42);
133+ cv::Mat flow;
134+
135+ ASSERT_THROW(of->calc(x, y, flow), cv::Exception);
136+}
137+
138+// make sure that autoSelectPatchSizeAndScales() works properly.
139+TEST(DenseOpticalFlow_DIS, InvalidImgSize_CoarsestLevelLessThanFinestLevel)
140+{
141+ cv::Ptr<cv::DISOpticalFlow> of = cv::DISOpticalFlow::create();
142+ const int mat_size = 80;
143+
144+ cv::Mat x(mat_size, mat_size, CV_8UC1, 42);
145+ cv::Mat y(mat_size, mat_size, CV_8UC1, 42);
146+ cv::Mat flow;
147+
148+ of->calc(x, y, flow);
149+
150+ ASSERT_EQ(flow.rows, mat_size);
151+ ASSERT_EQ(flow.cols, mat_size);
152+}
153+
154 TEST(DenseOpticalFlow_VariationalRefinement, ReferenceAccuracy)
155 {
156 Mat frame1, frame2, GT;
157
diff --git a/meta-oe/recipes-support/opencv/opencv_4.1.0.bb b/meta-oe/recipes-support/opencv/opencv_4.1.0.bb
index d781da600..de708fd06 100644
--- a/meta-oe/recipes-support/opencv/opencv_4.1.0.bb
+++ b/meta-oe/recipes-support/opencv/opencv_4.1.0.bb
@@ -50,6 +50,10 @@ SRC_URI = "git://github.com/opencv/opencv.git;name=opencv \
50 file://0001-Dont-use-isystem.patch \ 50 file://0001-Dont-use-isystem.patch \
51 file://0001-carotene-Replace-ipcp-unit-growth-with-ipa-cp-unit-g.patch \ 51 file://0001-carotene-Replace-ipcp-unit-growth-with-ipa-cp-unit-g.patch \
52 file://download.patch \ 52 file://download.patch \
53 file://CVE-2019-14491.patch \
54 file://CVE-2019-14493.patch \
55 file://CVE-2019-15939.patch \
56 file://CVE-2019-19624.patch \
53 " 57 "
54PV = "4.1.0" 58PV = "4.1.0"
55 59