Allow to read PNG image of color_type PNG_COLOR_TYPE_PALETTE with alpha channel
authorHanusz Leszek <leszek.hanusz@gmail.com>
Mon, 19 Aug 2013 17:05:37 +0000 (19:05 +0200)
committerHanusz Leszek <leszek.hanusz@gmail.com>
Wed, 21 Aug 2013 03:31:44 +0000 (05:31 +0200)
Correct reading PNG color type palette with or without alpha imread flags -1 or 1
Better not using pnginfo.h, using png_get_tRNS instead

modules/highgui/src/grfmt_png.cpp
modules/highgui/test/test_grfmt.cpp

index fb0fe6c..41bd58e 100644 (file)
@@ -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));
index 8366fcd..ed16d1c 100644 (file)
@@ -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