From 80ade96c8c60c174bf1d61d58a404b883337b3f6 Mon Sep 17 00:00:00 2001 From: Ganesh Kathiresan Date: Mon, 20 Jan 2020 16:30:45 +0530 Subject: [PATCH] Merge pull request #16309 from ganesh-k13:bugfix/imdecode-resize * Added flag handlers for imread and imdecode | Issue 16203 Undo imread change Added Imread resize tests Added imdecode flags check Added imdecode tests for resize Removed trailing whitespace Removed IMREAD_IGNORE_ORIENTATION check Added else condition Removed IMREAD_IGNORE_ORIENTATION check in decode Added HAVE_JPEG guards Added static_cast for Win32 Added resize for non jpegs Added tests for non jpeg resize case Fixed resize value in assert Changed tests to Value-Parameterized Tests Changed tests to Value-Parameterized Tests | handled >> in cpp Changed tests to Value-Parameterized Tests | removed trailing whitespace * imgcodecs: update test --- modules/imgcodecs/src/loadsave.cpp | 35 +++++++++--- modules/imgcodecs/test/test_precomp.hpp | 64 +++++++++++++++++++++ modules/imgcodecs/test/test_read_write.cpp | 89 ++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 7 deletions(-) diff --git a/modules/imgcodecs/src/loadsave.cpp b/modules/imgcodecs/src/loadsave.cpp index 0c22118..55008aa 100644 --- a/modules/imgcodecs/src/loadsave.cpp +++ b/modules/imgcodecs/src/loadsave.cpp @@ -423,12 +423,12 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 ) int scale_denom = 1; if( flags > IMREAD_LOAD_GDAL ) { - if( flags & IMREAD_REDUCED_GRAYSCALE_2 ) - scale_denom = 2; - else if( flags & IMREAD_REDUCED_GRAYSCALE_4 ) - scale_denom = 4; - else if( flags & IMREAD_REDUCED_GRAYSCALE_8 ) - scale_denom = 8; + if( flags & IMREAD_REDUCED_GRAYSCALE_2 ) + scale_denom = 2; + else if( flags & IMREAD_REDUCED_GRAYSCALE_4 ) + scale_denom = 4; + else if( flags & IMREAD_REDUCED_GRAYSCALE_8 ) + scale_denom = 8; } /// set the scale_denom in the driver @@ -766,6 +766,20 @@ imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 ) if( !decoder ) return 0; + int scale_denom = 1; + if( flags > IMREAD_LOAD_GDAL ) + { + if( flags & IMREAD_REDUCED_GRAYSCALE_2 ) + scale_denom = 2; + else if( flags & IMREAD_REDUCED_GRAYSCALE_4 ) + scale_denom = 4; + else if( flags & IMREAD_REDUCED_GRAYSCALE_8 ) + scale_denom = 8; + } + + /// set the scale_denom in the driver + decoder->setScale( scale_denom ); + if( !decoder->setSource(buf_row) ) { filename = tempfile(); @@ -861,7 +875,7 @@ imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 ) { std::cerr << "imdecode_('" << filename << "'): can't read data: unknown exception" << std::endl << std::flush; } - decoder.release(); + if (!filename.empty()) { if (0 != remove(filename.c_str())) @@ -879,6 +893,13 @@ imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 ) return 0; } + if( decoder->setScale( scale_denom ) > 1 ) // if decoder is JpegDecoder then decoder->setScale always returns 1 + { + resize( *mat, *mat, Size( size.width / scale_denom, size.height / scale_denom ), 0, 0, INTER_LINEAR_EXACT); + } + + decoder.release(); + return hdrtype == LOAD_CVMAT ? (void*)matrix : hdrtype == LOAD_IMAGE ? (void*)image : (void*)mat; } diff --git a/modules/imgcodecs/test/test_precomp.hpp b/modules/imgcodecs/test/test_precomp.hpp index 4fc692c..3bd4221 100644 --- a/modules/imgcodecs/test/test_precomp.hpp +++ b/modules/imgcodecs/test/test_precomp.hpp @@ -8,4 +8,68 @@ #include "opencv2/imgcodecs.hpp" #include "opencv2/imgproc/imgproc_c.h" +namespace cv { + +static inline +void PrintTo(const ImreadModes& val, std::ostream* os) +{ + int v = val; + if (v == IMREAD_UNCHANGED && (v & IMREAD_IGNORE_ORIENTATION) != 0) + { + CV_Assert(IMREAD_UNCHANGED == -1); + *os << "IMREAD_UNCHANGED"; + return; + } + if ((v & IMREAD_COLOR) != 0) + { + CV_Assert(IMREAD_COLOR == 1); + v &= ~IMREAD_COLOR; + *os << "IMREAD_COLOR" << (v == 0 ? "" : " | "); + } + else + { + CV_Assert(IMREAD_GRAYSCALE == 0); + *os << "IMREAD_GRAYSCALE" << (v == 0 ? "" : " | "); + } + if ((v & IMREAD_ANYDEPTH) != 0) + { + v &= ~IMREAD_ANYDEPTH; + *os << "IMREAD_ANYDEPTH" << (v == 0 ? "" : " | "); + } + if ((v & IMREAD_ANYCOLOR) != 0) + { + v &= ~IMREAD_ANYCOLOR; + *os << "IMREAD_ANYCOLOR" << (v == 0 ? "" : " | "); + } + if ((v & IMREAD_LOAD_GDAL) != 0) + { + v &= ~IMREAD_LOAD_GDAL; + *os << "IMREAD_LOAD_GDAL" << (v == 0 ? "" : " | "); + } + if ((v & IMREAD_IGNORE_ORIENTATION) != 0) + { + v &= ~IMREAD_IGNORE_ORIENTATION; + *os << "IMREAD_IGNORE_ORIENTATION" << (v == 0 ? "" : " | "); + } + switch (v) + { + case IMREAD_UNCHANGED: return; + case IMREAD_GRAYSCALE: return; + case IMREAD_COLOR: return; + case IMREAD_ANYDEPTH: return; + case IMREAD_ANYCOLOR: return; + case IMREAD_LOAD_GDAL: return; + case IMREAD_REDUCED_GRAYSCALE_2: // fallthru + case IMREAD_REDUCED_COLOR_2: *os << "REDUCED_2"; return; + case IMREAD_REDUCED_GRAYSCALE_4: // fallthru + case IMREAD_REDUCED_COLOR_4: *os << "REDUCED_4"; return; + case IMREAD_REDUCED_GRAYSCALE_8: // fallthru + case IMREAD_REDUCED_COLOR_8: *os << "REDUCED_8"; return; + case IMREAD_IGNORE_ORIENTATION: return; + } // don't use "default:" to emit compiler warnings + *os << "IMREAD_UNKNOWN(" << (int)v << ")"; +} + +} // namespace + #endif diff --git a/modules/imgcodecs/test/test_read_write.cpp b/modules/imgcodecs/test/test_read_write.cpp index f0f4139..6396200 100644 --- a/modules/imgcodecs/test/test_read_write.cpp +++ b/modules/imgcodecs/test/test_read_write.cpp @@ -5,6 +5,95 @@ namespace opencv_test { namespace { +/* < , > */ +typedef tuple< tuple, tuple > Imgcodecs_Resize_t; + +typedef testing::TestWithParam< Imgcodecs_Resize_t > Imgcodecs_Resize; + +/* resize_flag_and_dims = */ +const tuple resize_flag_and_dims[] = +{ + make_tuple(IMREAD_UNCHANGED, 1), + make_tuple(IMREAD_REDUCED_GRAYSCALE_2, 2), + make_tuple(IMREAD_REDUCED_GRAYSCALE_4, 4), + make_tuple(IMREAD_REDUCED_GRAYSCALE_8, 8), + make_tuple(IMREAD_REDUCED_COLOR_2, 2), + make_tuple(IMREAD_REDUCED_COLOR_4, 4), + make_tuple(IMREAD_REDUCED_COLOR_8, 8) +}; + +const tuple images[] = +{ +#ifdef HAVE_JPEG + make_tuple("../cv/imgproc/stuff.jpg", Size(640, 480)), +#endif +#ifdef HAVE_PNG + make_tuple("../cv/shared/pic1.png", Size(400, 300)), +#endif +}; + +TEST_P(Imgcodecs_Resize, imread_reduce_flags) +{ + const string file_name = findDataFile(get<0>(get<0>(GetParam()))); + const Size imageSize = get<1>(get<0>(GetParam())); + + const int imread_flag = get<0>(get<1>(GetParam())); + const int scale = get<1>(get<1>(GetParam())); + + const int cols = imageSize.width / scale; + const int rows = imageSize.height / scale; + { + Mat img = imread(file_name, imread_flag); + ASSERT_FALSE(img.empty()); + EXPECT_EQ(cols, img.cols); + EXPECT_EQ(rows, img.rows); + } +} + +//================================================================================================== + +TEST_P(Imgcodecs_Resize, imdecode_reduce_flags) +{ + const string file_name = findDataFile(get<0>(get<0>(GetParam()))); + const Size imageSize = get<1>(get<0>(GetParam())); + + const int imread_flag = get<0>(get<1>(GetParam())); + const int scale = get<1>(get<1>(GetParam())); + + const int cols = imageSize.width / scale; + const int rows = imageSize.height / scale; + + const std::ios::openmode mode = std::ios::in | std::ios::binary; + std::ifstream ifs(file_name.c_str(), mode); + ASSERT_TRUE(ifs.is_open()); + + ifs.seekg(0, std::ios::end); + const size_t sz = static_cast(ifs.tellg()); + ifs.seekg(0, std::ios::beg); + + std::vector content(sz); + ifs.read((char*)content.data(), sz); + ASSERT_FALSE(ifs.fail()); + + { + Mat img = imdecode(Mat(content), imread_flag); + ASSERT_FALSE(img.empty()); + EXPECT_EQ(cols, img.cols); + EXPECT_EQ(rows, img.rows); + } +} + +//================================================================================================== + +INSTANTIATE_TEST_CASE_P(/*nothing*/, Imgcodecs_Resize, + testing::Combine( + testing::ValuesIn(images), + testing::ValuesIn(resize_flag_and_dims) + ) + ); + +//================================================================================================== + TEST(Imgcodecs_Image, read_write_bmp) { const size_t IMAGE_COUNT = 10; -- 2.7.4