diff --git a/modules/highgui/src/grfmt_png.cpp b/modules/highgui/src/grfmt_png.cpp index fb0fe6c391..41bd58e80c 100644 --- a/modules/highgui/src/grfmt_png.cpp +++ b/modules/highgui/src/grfmt_png.cpp @@ -171,7 +171,9 @@ bool PngDecoder::readHeader() if( !m_buf.empty() || m_f ) { png_uint_32 wdth, hght; - int bit_depth, color_type; + int bit_depth, color_type, num_trans=0; + png_bytep trans; + png_color_16p trans_values; png_read_info( png_ptr, info_ptr ); @@ -187,15 +189,22 @@ bool PngDecoder::readHeader() { switch(color_type) { - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_PALETTE: - m_type = CV_8UC3; - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - m_type = CV_8UC4; - break; - default: - m_type = CV_8UC1; + case PNG_COLOR_TYPE_RGB: + m_type = CV_8UC3; + break; + case PNG_COLOR_TYPE_PALETTE: + png_get_tRNS( png_ptr, info_ptr, &trans, &num_trans, &trans_values); + //Check if there is a transparency value in the palette + if ( num_trans > 0 ) + m_type = CV_8UC4; + else + m_type = CV_8UC3; + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + m_type = CV_8UC4; + break; + default: + m_type = CV_8UC1; } if( bit_depth == 16 ) m_type = CV_MAKETYPE(CV_16U, CV_MAT_CN(m_type)); diff --git a/modules/highgui/test/test_grfmt.cpp b/modules/highgui/test/test_grfmt.cpp index 8366fcdffc..ed16d1cde2 100644 --- a/modules/highgui/test/test_grfmt.cpp +++ b/modules/highgui/test/test_grfmt.cpp @@ -280,6 +280,98 @@ TEST(Highgui_ImreadVSCvtColor, regression) EXPECT_LT(actual_avg_diff, MAX_MEAN_DIFF); EXPECT_LT(actual_maxval, MAX_ABS_DIFF); } + +//Test OpenCV issue 3075 is solved +class CV_GrfmtReadPNGColorPaletteWithAlphaTest : public cvtest::BaseTest +{ +public: + void run(int) + { + try + { + // First Test : Read PNG with alpha, imread flag -1 + Mat img = imread(string(ts->get_data_path()) + "readwrite/color_palette_alpha.png",-1); + if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + + ASSERT_TRUE(img.channels() == 4); + + uint8_t* img_data = (uint8_t*)img.data; + + // Verification first pixel is red in BGRA + ASSERT_TRUE(img_data[0] == 0x00); + ASSERT_TRUE(img_data[1] == 0x00); + ASSERT_TRUE(img_data[2] == 0xFF); + ASSERT_TRUE(img_data[3] == 0xFF); + + // Verification second pixel is red in BGRA + ASSERT_TRUE(img_data[4] == 0x00); + ASSERT_TRUE(img_data[5] == 0x00); + ASSERT_TRUE(img_data[6] == 0xFF); + ASSERT_TRUE(img_data[7] == 0xFF); + + // Second Test : Read PNG without alpha, imread flag -1 + img = imread(string(ts->get_data_path()) + "readwrite/color_palette_no_alpha.png",-1); + if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + + ASSERT_TRUE(img.channels() == 3); + + img_data = (uint8_t*)img.data; + + // Verification first pixel is red in BGR + ASSERT_TRUE(img_data[0] == 0x00); + ASSERT_TRUE(img_data[1] == 0x00); + ASSERT_TRUE(img_data[2] == 0xFF); + + // Verification second pixel is red in BGR + ASSERT_TRUE(img_data[3] == 0x00); + ASSERT_TRUE(img_data[4] == 0x00); + ASSERT_TRUE(img_data[5] == 0xFF); + + // Third Test : Read PNG with alpha, imread flag 1 + img = imread(string(ts->get_data_path()) + "readwrite/color_palette_alpha.png",1); + if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + + ASSERT_TRUE(img.channels() == 3); + + img_data = (uint8_t*)img.data; + + // Verification first pixel is red in BGR + ASSERT_TRUE(img_data[0] == 0x00); + ASSERT_TRUE(img_data[1] == 0x00); + ASSERT_TRUE(img_data[2] == 0xFF); + + // Verification second pixel is red in BGR + ASSERT_TRUE(img_data[3] == 0x00); + ASSERT_TRUE(img_data[4] == 0x00); + ASSERT_TRUE(img_data[5] == 0xFF); + + // Fourth Test : Read PNG without alpha, imread flag 1 + img = imread(string(ts->get_data_path()) + "readwrite/color_palette_no_alpha.png",1); + if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); + + ASSERT_TRUE(img.channels() == 3); + + img_data = (uint8_t*)img.data; + + // Verification first pixel is red in BGR + ASSERT_TRUE(img_data[0] == 0x00); + ASSERT_TRUE(img_data[1] == 0x00); + ASSERT_TRUE(img_data[2] == 0xFF); + + // Verification second pixel is red in BGR + ASSERT_TRUE(img_data[3] == 0x00); + ASSERT_TRUE(img_data[4] == 0x00); + ASSERT_TRUE(img_data[5] == 0xFF); + } + catch(...) + { + ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION); + } + ts->set_failed_test_info(cvtest::TS::OK); + } +}; + +TEST(Highgui_Image, read_png_color_palette_with_alpha) { CV_GrfmtReadPNGColorPaletteWithAlphaTest test; test.safe_run(); } #endif #ifdef HAVE_JPEG