mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +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 buf Input array or vector of bytes.
|
||||||
@param flags The same flags as in cv::imread, see cv::ImreadModes.
|
@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 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.
|
/** @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();
|
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();
|
CV_TRACE_FUNCTION();
|
||||||
|
|
||||||
Mat buf = _buf.getMat();
|
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,
|
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 int mode = GetParam();
|
||||||
const string root = cvtest::TS::ptr()->get_data_path();
|
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");
|
FILE* fp = fopen(filename.c_str(), "rb");
|
||||||
ASSERT_TRUE(fp != NULL);
|
ASSERT_TRUE(fp != NULL);
|
||||||
fseek(fp, 0, SEEK_END);
|
fseek(fp, 0, SEEK_END);
|
||||||
long pos = ftell(fp);
|
const size_t file_size = ftell(fp);
|
||||||
|
|
||||||
std::vector<uchar> buf;
|
|
||||||
buf.resize((size_t)pos);
|
|
||||||
fseek(fp, 0, SEEK_SET);
|
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);
|
fclose(fp);
|
||||||
|
ASSERT_EQ(file_size, actual_read);
|
||||||
|
ASSERT_EQ(file_size, static_cast<size_t>(buf.size()));
|
||||||
|
|
||||||
bool res = imdecodemulti(buf, mode, pages);
|
bool res = imdecodemulti(buf, mode, pages);
|
||||||
ASSERT_TRUE(res == true);
|
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[] =
|
const int all_modes[] =
|
||||||
{
|
{
|
||||||
IMREAD_UNCHANGED,
|
IMREAD_UNCHANGED,
|
||||||
|
Loading…
Reference in New Issue
Block a user