diff --git a/modules/imgcodecs/src/grfmt_png.cpp b/modules/imgcodecs/src/grfmt_png.cpp index ffcc0f29be..1001ff6eec 100644 --- a/modules/imgcodecs/src/grfmt_png.cpp +++ b/modules/imgcodecs/src/grfmt_png.cpp @@ -451,6 +451,9 @@ bool PngDecoder::readData( Mat& img ) delay_den = 100; m_animation.durations.push_back(cvRound(1000.*delay_num/delay_den)); + if (mat_cur.depth() == CV_16U && img.depth() == CV_8U) + mat_cur.convertTo(mat_cur, CV_8U, 1. / 255); + if (mat_cur.channels() == img.channels()) mat_cur.copyTo(img); else if (img.channels() == 1) @@ -485,7 +488,7 @@ bool PngDecoder::readData( Mat& img ) return false; } // Asking for blend over with no alpha is invalid. - if (bop == 1 && img.channels() != 4) + if (bop == 1 && mat_cur.channels() != 4) { return false; } @@ -514,6 +517,9 @@ bool PngDecoder::readData( Mat& img ) delay_den = 100; m_animation.durations.push_back(cvRound(1000.*delay_num/delay_den)); + if (mat_cur.depth() == CV_16U && img.depth() == CV_8U) + mat_cur.convertTo(mat_cur, CV_8U, 1. / 255); + if (mat_cur.channels() == img.channels()) mat_cur.copyTo(img); else if (img.channels() == 1) @@ -775,6 +781,9 @@ bool PngDecoder::processing_start(void* frame_ptr, const Mat& img) else png_set_rgb_to_gray(m_png_ptr, 1, 0.299, 0.587); // RGB->Gray + if (!isBigEndian() && m_bit_depth == 16) + png_set_swap(m_png_ptr); + for (size_t i = 0; i < m_chunksInfo.size(); i++) png_process_data(m_png_ptr, m_info_ptr, m_chunksInfo[i].p.data(), m_chunksInfo[i].p.size()); diff --git a/modules/imgcodecs/src/loadsave.cpp b/modules/imgcodecs/src/loadsave.cpp index 0bf90f2aa2..fd547a378a 100644 --- a/modules/imgcodecs/src/loadsave.cpp +++ b/modules/imgcodecs/src/loadsave.cpp @@ -505,7 +505,7 @@ imread_( const String& filename, int flags, OutputArray mat ) { if (decoder->readData(real_mat)) { - CV_CheckTrue(original_ptr == real_mat.data, "Internal imread issue"); + CV_CheckTrue((decoder->getFrameCount() > 1) || original_ptr == real_mat.data, "Internal imread issue"); success = true; } } diff --git a/modules/imgcodecs/test/test_animation.cpp b/modules/imgcodecs/test/test_animation.cpp index e566bcbd49..ece0d19d29 100644 --- a/modules/imgcodecs/test/test_animation.cpp +++ b/modules/imgcodecs/test/test_animation.cpp @@ -626,7 +626,7 @@ TEST(Imgcodecs_APNG, imencode_animation) EXPECT_TRUE(imencodeanimation(".png", gt_animation, buf)); EXPECT_TRUE(imdecodeanimation(buf, mem_animation)); - EXPECT_EQ(mem_animation.frames.size(), gt_animation.frames.size()); + EXPECT_EQ(mem_animation.frames.size(), gt_animation.frames.size()); EXPECT_EQ(mem_animation.bgcolor, gt_animation.bgcolor); EXPECT_EQ(mem_animation.loop_count, gt_animation.loop_count); for (size_t i = 0; i < gt_animation.frames.size(); i++) @@ -638,4 +638,61 @@ TEST(Imgcodecs_APNG, imencode_animation) #endif // HAVE_PNG +#if defined(HAVE_PNG) || defined(HAVE_SPNG) + +TEST(Imgcodecs_APNG, imread_animation_16u) +{ + // Set the path to the test image directory and filename for loading. + const string root = cvtest::TS::ptr()->get_data_path(); + const string filename = root + "readwrite/033.png"; + + Mat img = imread(filename, IMREAD_UNCHANGED); + ASSERT_FALSE(img.empty()); + EXPECT_TRUE(img.type() == CV_16UC4); + EXPECT_EQ(0, img.at(0, 0)); + EXPECT_EQ(0, img.at(0, 1)); + EXPECT_EQ(65280, img.at(0, 2)); + EXPECT_EQ(65535, img.at(0, 3)); + + img = imread(filename, IMREAD_GRAYSCALE); + ASSERT_FALSE(img.empty()); + EXPECT_TRUE(img.type() == CV_8UC1); + EXPECT_EQ(76, img.at(0, 0)); + + img = imread(filename, IMREAD_COLOR); + ASSERT_FALSE(img.empty()); + EXPECT_TRUE(img.type() == CV_8UC3); + EXPECT_EQ(0, img.at(0, 0)); + EXPECT_EQ(0, img.at(0, 1)); + EXPECT_EQ(255, img.at(0, 2)); + + img = imread(filename, IMREAD_COLOR_RGB); + ASSERT_FALSE(img.empty()); + EXPECT_TRUE(img.type() == CV_8UC3); + EXPECT_EQ(255, img.at(0, 0)); + EXPECT_EQ(0, img.at(0, 1)); + EXPECT_EQ(0, img.at(0, 2)); + + img = imread(filename, IMREAD_ANYDEPTH); + ASSERT_FALSE(img.empty()); + EXPECT_TRUE(img.type() == CV_16UC1); + EXPECT_EQ(19519, img.at(0, 0)); + + img = imread(filename, IMREAD_COLOR | IMREAD_ANYDEPTH); + ASSERT_FALSE(img.empty()); + EXPECT_TRUE(img.type() == CV_16UC3); + EXPECT_EQ(0, img.at(0, 0)); + EXPECT_EQ(0, img.at(0, 1)); + EXPECT_EQ(65280, img.at(0, 2)); + + img = imread(filename, IMREAD_COLOR_RGB | IMREAD_ANYDEPTH); + ASSERT_FALSE(img.empty()); + EXPECT_TRUE(img.type() == CV_16UC3); + EXPECT_EQ(65280, img.at(0, 0)); + EXPECT_EQ(0, img.at(0, 1)); + EXPECT_EQ(0, img.at(0, 2)); +} + +#endif // HAVE_PNG || HAVE_SPNG + }} // namespace