mirror of
https://github.com/opencv/opencv.git
synced 2024-11-27 20:50:25 +08:00
Merge pull request #24405 from kochanczyk:4.x
Extend the signature of imdecodemulti() #24405 (Edited after addressing Reviewers' comments.) Add an argument to `imdecodemulti()` to enable optional selection of pages of multi-page images. Be default, all pages are decoded. If used, the additional argument may specify a continuous selection of pages to decode. ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [X] I agree to contribute to the project under Apache 2 License. - [X] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
parent
617d7ff575
commit
e9e6b1e22c
@ -337,8 +337,9 @@ See cv::imreadmulti for the list of supported formats and flags description.
|
||||
@param buf Input array or vector of bytes.
|
||||
@param flags The same flags as in cv::imread, see cv::ImreadModes.
|
||||
@param mats A vector of Mat objects holding each page, if more than one.
|
||||
@param range A continuous selection of pages.
|
||||
*/
|
||||
CV_EXPORTS_W bool imdecodemulti(InputArray buf, int flags, CV_OUT std::vector<Mat>& mats);
|
||||
CV_EXPORTS_W bool imdecodemulti(InputArray buf, int flags, CV_OUT std::vector<Mat>& mats, const cv::Range& range = Range::all());
|
||||
|
||||
/** @brief Encodes an image into a memory buffer.
|
||||
|
||||
|
@ -1095,12 +1095,21 @@ imdecodemulti_(const Mat& buf, int flags, std::vector<Mat>& mats, int start, int
|
||||
return !mats.empty();
|
||||
}
|
||||
|
||||
bool imdecodemulti(InputArray _buf, int flags, CV_OUT std::vector<Mat>& mats)
|
||||
bool imdecodemulti(InputArray _buf, int flags, CV_OUT std::vector<Mat>& mats, const Range& range)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
Mat buf = _buf.getMat();
|
||||
return imdecodemulti_(buf, flags, mats, 0, -1);
|
||||
if (range == Range::all())
|
||||
{
|
||||
return imdecodemulti_(buf, flags, mats, 0, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_CheckGE(range.start, 0, "Range start cannot be negative.");
|
||||
CV_CheckGT(range.size(), 0, "Range cannot be empty.");
|
||||
return imdecodemulti_(buf, flags, mats, range.start, range.size());
|
||||
}
|
||||
}
|
||||
|
||||
bool imencode( const String& ext, InputArray _image,
|
||||
|
@ -965,7 +965,7 @@ TEST_P(Imgcodecs_Tiff_Modes, decode_multipage)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Imgcodecs_Tiff_Modes, decode_multipage_use_memory_buffer)
|
||||
TEST_P(Imgcodecs_Tiff_Modes, decode_multipage_use_memory_buffer_all_pages)
|
||||
{
|
||||
const int mode = GetParam();
|
||||
const string root = cvtest::TS::ptr()->get_data_path();
|
||||
@ -984,13 +984,14 @@ TEST_P(Imgcodecs_Tiff_Modes, decode_multipage_use_memory_buffer)
|
||||
FILE* fp = fopen(filename.c_str(), "rb");
|
||||
ASSERT_TRUE(fp != NULL);
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long pos = ftell(fp);
|
||||
|
||||
std::vector<uchar> buf;
|
||||
buf.resize((size_t)pos);
|
||||
const size_t file_size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
buf.resize(fread(&buf[0], 1, buf.size(), fp));
|
||||
|
||||
std::vector<uchar> buf(file_size);
|
||||
const size_t actual_read = fread(&buf[0], 1, file_size, fp);
|
||||
fclose(fp);
|
||||
ASSERT_EQ(file_size, actual_read);
|
||||
ASSERT_EQ(file_size, static_cast<size_t>(buf.size()));
|
||||
|
||||
bool res = imdecodemulti(buf, mode, pages);
|
||||
ASSERT_TRUE(res == true);
|
||||
@ -1002,6 +1003,60 @@ TEST_P(Imgcodecs_Tiff_Modes, decode_multipage_use_memory_buffer)
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Imgcodecs_Tiff_Modes, decode_multipage_use_memory_buffer_selected_pages)
|
||||
{
|
||||
const int mode = GetParam();
|
||||
const string root = cvtest::TS::ptr()->get_data_path();
|
||||
const string filename = root + "readwrite/multipage.tif";
|
||||
const string page_files[] = {
|
||||
"readwrite/multipage_p1.tif",
|
||||
"readwrite/multipage_p2.tif",
|
||||
"readwrite/multipage_p3.tif",
|
||||
"readwrite/multipage_p4.tif",
|
||||
"readwrite/multipage_p5.tif",
|
||||
"readwrite/multipage_p6.tif"
|
||||
};
|
||||
const size_t page_count = sizeof(page_files) / sizeof(page_files[0]);
|
||||
|
||||
FILE* fp = fopen(filename.c_str(), "rb");
|
||||
ASSERT_TRUE(fp != NULL);
|
||||
fseek(fp, 0, SEEK_END);
|
||||
const size_t file_size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
std::vector<uchar> buf(file_size);
|
||||
const size_t actual_read = fread(&buf[0], 1, file_size, fp);
|
||||
fclose(fp);
|
||||
ASSERT_EQ(file_size, actual_read);
|
||||
ASSERT_EQ(file_size, static_cast<size_t>(buf.size()));
|
||||
|
||||
const Range range(1, page_count - 1);
|
||||
ASSERT_GE(range.size(), 1);
|
||||
|
||||
vector<Mat> middle_pages_from_imread;
|
||||
for (int page_i = range.start; page_i < range.end; page_i++)
|
||||
{
|
||||
const Mat page = imread(root + page_files[page_i], mode);
|
||||
middle_pages_from_imread.push_back(page);
|
||||
}
|
||||
ASSERT_EQ(
|
||||
static_cast<size_t>(range.size()),
|
||||
static_cast<size_t>(middle_pages_from_imread.size())
|
||||
);
|
||||
|
||||
vector<Mat> middle_pages_from_imdecodemulti;
|
||||
const bool res = imdecodemulti(buf, mode, middle_pages_from_imdecodemulti, range);
|
||||
ASSERT_TRUE(res == true);
|
||||
EXPECT_EQ(middle_pages_from_imread.size(), middle_pages_from_imdecodemulti.size());
|
||||
|
||||
for (int i = 0, e = range.size(); i < e; i++)
|
||||
{
|
||||
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0),
|
||||
middle_pages_from_imread[i],
|
||||
middle_pages_from_imdecodemulti[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const int all_modes[] =
|
||||
{
|
||||
IMREAD_UNCHANGED,
|
||||
|
Loading…
Reference in New Issue
Block a user