| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639 |
- // This file is part of OpenCV project.
- // It is subject to the license terms in the LICENSE file found in the top-level directory
- // of this distribution and at http://opencv.org/license.html
- #include "test_precomp.hpp"
- #include "test_common.hpp"
- namespace opencv_test { namespace {
- #if defined(HAVE_PNG) || defined(HAVE_SPNG)
- TEST(Imgcodecs_Png, write_big)
- {
- const string root = cvtest::TS::ptr()->get_data_path();
- const string filename = root + "readwrite/read.png";
- Mat img;
- ASSERT_NO_THROW(img = imread(filename));
- ASSERT_FALSE(img.empty());
- EXPECT_EQ(13043, img.cols);
- EXPECT_EQ(13917, img.rows);
- vector<uchar> buff;
- bool status = false;
- ASSERT_NO_THROW(status = imencode(".png", img, buff, { IMWRITE_PNG_ZLIBBUFFER_SIZE, 1024*1024 }));
- ASSERT_TRUE(status);
- #ifdef HAVE_PNG
- EXPECT_EQ((size_t)816219, buff.size());
- #else
- EXPECT_EQ((size_t)817407, buff.size());
- #endif
- }
- TEST(Imgcodecs_Png, encode)
- {
- vector<uchar> buff;
- Mat img_gt = Mat::zeros(1000, 1000, CV_8U);
- vector<int> param;
- param.push_back(IMWRITE_PNG_COMPRESSION);
- param.push_back(3); //default(3) 0-9.
- bool status = false;
- EXPECT_NO_THROW(status = imencode(".png", img_gt, buff, param));
- ASSERT_TRUE(status);
- Mat img;
- EXPECT_NO_THROW(img = imdecode(buff, IMREAD_ANYDEPTH)); // hang
- EXPECT_FALSE(img.empty());
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, img_gt);
- }
- TEST(Imgcodecs_Png, regression_ImreadVSCvtColor)
- {
- const string root = cvtest::TS::ptr()->get_data_path();
- const string imgName = root + "../cv/shared/lena.png";
- Mat original_image = imread(imgName);
- Mat gray_by_codec = imread(imgName, IMREAD_GRAYSCALE);
- Mat gray_by_cvt;
- cvtColor(original_image, gray_by_cvt, COLOR_BGR2GRAY);
- Mat diff;
- absdiff(gray_by_codec, gray_by_cvt, diff);
- EXPECT_LT(cvtest::mean(diff)[0], 1.);
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(10, 0), gray_by_codec, gray_by_cvt);
- }
- // Test OpenCV issue 3075 is solved
- TEST(Imgcodecs_Png, read_color_palette_with_alpha)
- {
- const string root = cvtest::TS::ptr()->get_data_path();
- Mat img;
- // First Test : Read PNG with alpha, imread flag -1
- img = imread(root + "readwrite/color_palette_alpha.png", IMREAD_UNCHANGED);
- ASSERT_FALSE(img.empty());
- ASSERT_TRUE(img.channels() == 4);
- // pixel is red in BGRA
- EXPECT_EQ(img.at<Vec4b>(0, 0), Vec4b(0, 0, 255, 255));
- EXPECT_EQ(img.at<Vec4b>(0, 1), Vec4b(0, 0, 255, 255));
- // Second Test : Read PNG without alpha, imread flag -1
- img = imread(root + "readwrite/color_palette_no_alpha.png", IMREAD_UNCHANGED);
- ASSERT_FALSE(img.empty());
- ASSERT_TRUE(img.channels() == 3);
- // pixel is red in BGR
- EXPECT_EQ(img.at<Vec3b>(0, 0), Vec3b(0, 0, 255));
- EXPECT_EQ(img.at<Vec3b>(0, 1), Vec3b(0, 0, 255));
- // Third Test : Read PNG with alpha, imread flag 1
- img = imread(root + "readwrite/color_palette_alpha.png", IMREAD_COLOR);
- ASSERT_FALSE(img.empty());
- ASSERT_TRUE(img.channels() == 3);
- // pixel is red in BGR
- EXPECT_EQ(img.at<Vec3b>(0, 0), Vec3b(0, 0, 255));
- EXPECT_EQ(img.at<Vec3b>(0, 1), Vec3b(0, 0, 255));
- img = imread(root + "readwrite/color_palette_alpha.png", IMREAD_COLOR_RGB);
- ASSERT_FALSE(img.empty());
- ASSERT_TRUE(img.channels() == 3);
- // pixel is red in RGB
- EXPECT_EQ(img.at<Vec3b>(0, 0), Vec3b(255, 0, 0));
- EXPECT_EQ(img.at<Vec3b>(0, 1), Vec3b(255, 0, 0));
- // Fourth Test : Read PNG without alpha, imread flag 1
- img = imread(root + "readwrite/color_palette_no_alpha.png", IMREAD_COLOR);
- ASSERT_FALSE(img.empty());
- ASSERT_TRUE(img.channels() == 3);
- // pixel is red in BGR
- EXPECT_EQ(img.at<Vec3b>(0, 0), Vec3b(0, 0, 255));
- EXPECT_EQ(img.at<Vec3b>(0, 1), Vec3b(0, 0, 255));
- img = imread(root + "readwrite/color_palette_no_alpha.png", IMREAD_COLOR_RGB);
- ASSERT_FALSE(img.empty());
- ASSERT_TRUE(img.channels() == 3);
- // pixel is red in RGB
- EXPECT_EQ(img.at<Vec3b>(0, 0), Vec3b(255, 0, 0));
- EXPECT_EQ(img.at<Vec3b>(0, 1), Vec3b(255, 0, 0));
- }
- // IHDR shall be first.
- // See https://github.com/opencv/opencv/issues/27295
- TEST(Imgcodecs_Png, decode_regression27295)
- {
- vector<uchar> buff;
- Mat src = Mat::zeros(240, 180, CV_8UC3);
- vector<int> param;
- EXPECT_NO_THROW(imencode(".png", src, buff, param));
- Mat img;
- // If IHDR chunk found as the first chunk, output shall not be empty.
- // 8 means PNG signature length.
- // 4 means length field(uint32_t).
- EXPECT_EQ(buff[8+4+0], 'I');
- EXPECT_EQ(buff[8+4+1], 'H');
- EXPECT_EQ(buff[8+4+2], 'D');
- EXPECT_EQ(buff[8+4+3], 'R');
- EXPECT_NO_THROW(img = imdecode(buff, IMREAD_COLOR));
- EXPECT_FALSE(img.empty());
- // If Non-IHDR chunk found as the first chunk, output shall be empty.
- buff[8+4+0] = 'i'; // Not 'I'
- buff[8+4+1] = 'H';
- buff[8+4+2] = 'D';
- buff[8+4+3] = 'R';
- EXPECT_NO_THROW(img = imdecode(buff, IMREAD_COLOR));
- EXPECT_TRUE(img.empty());
- // If CgBI chunk (Apple private) found as the first chunk, output shall be empty with special message.
- buff[8+4+0] = 'C';
- buff[8+4+1] = 'g';
- buff[8+4+2] = 'B';
- buff[8+4+3] = 'I';
- EXPECT_NO_THROW(img = imdecode(buff, IMREAD_COLOR));
- EXPECT_TRUE(img.empty());
- }
- // The program must not crash even when decoding a corrupted APNG image.
- // See https://github.com/opencv/opencv/issues/27744
- #if defined(HAVE_PNG) // APNG is supported only with using libpng
- TEST(Imgcodecs_Png, decode_regression27744)
- {
- // Create APNG stream
- Animation anim;
- for(size_t i = 0 ; i < 3 ; i++) {
- Mat frame(120, 120, CV_8UC3, Scalar(0,0,0));
- putText(frame, cv::format("%d", static_cast<int>(i)), Point(5, 28), FONT_HERSHEY_SIMPLEX, .5, Scalar(100, 255, 0, 255), 2);
- anim.frames.push_back(frame);
- anim.durations.push_back(30);
- }
- bool ret = false;
- vector<uchar> buff;
- EXPECT_NO_THROW(ret = imencodeanimation(".png", anim, buff));
- ASSERT_TRUE(ret) << "imencodeanimation() returns false";
- // Find IDAT chunk
- const vector<uchar> IDAT = {'I', 'D', 'A', 'T' };
- std::vector<uchar>::iterator it = std::search(buff.begin(), buff.end(), IDAT.begin(), IDAT.end());
- ASSERT_FALSE(it == buff.end()) << "IDAT chunk not found";
- // Determine the range to test
- // APNG stream contains as { len0, len1, len2, len3, 'I', 'D', 'A' 'T', ... }
- size_t idx = std::distance(buff.begin(), it); // 'I' position
- size_t len = (buff[idx-4] << 24) + (buff[idx-3] << 16) +
- (buff[idx-2] << 8) + (buff[idx-1]); // IDAT chunk length
- idx = idx + 4; // Move to IDAT body
- // Test
- for(size_t i = 0; i < len; i++, idx++) {
- vector<uint8_t> work = buff;
- work[idx] = static_cast<uint8_t>((static_cast<uint32_t>(work[idx]) + 1) & 0xff);
- Mat dst;
- EXPECT_NO_THROW(dst = imdecode(work, cv::IMREAD_COLOR));
- if(dst.empty()) {
- // libpng detects some error, but the program is not crashed. Test is passed.
- break;
- }
- }
- }
- #endif
- typedef testing::TestWithParam<string> Imgcodecs_Png_PngSuite;
- // Parameterized test for decoding PNG files from the PNGSuite test set
- TEST_P(Imgcodecs_Png_PngSuite, decode)
- {
- // Construct full paths for the PNG image and corresponding ground truth XML file
- const string root = cvtest::TS::ptr()->get_data_path();
- const string filename = root + "pngsuite/" + GetParam() + ".png";
- const string xml_filename = root + "pngsuite/" + GetParam() + ".xml";
- // Load the XML file containing the ground truth data
- FileStorage fs(xml_filename, FileStorage::READ);
- ASSERT_TRUE(fs.isOpened()); // Ensure the file was opened successfully
- // Load the image using IMREAD_UNCHANGED to preserve original format
- Mat src = imread(filename, IMREAD_UNCHANGED);
- ASSERT_FALSE(src.empty()); // Ensure the image was loaded successfully
- // Load the ground truth matrix from XML
- Mat gt;
- fs.getFirstTopLevelNode() >> gt;
- // Compare the image loaded with IMREAD_UNCHANGED to the ground truth
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), src, gt);
- // Declare matrices for ground truth in different imread flag combinations
- Mat gt_0, gt_1, gt_2, gt_3, gt_256, gt_258;
- // Handle grayscale 8-bit and 16-bit images
- if (gt.channels() == 1)
- {
- gt.copyTo(gt_2); // For IMREAD_ANYDEPTH
- if (gt.depth() == CV_16U)
- gt_2.convertTo(gt_0, CV_8U, 1. / 256);
- else
- gt_0 = gt_2; // For IMREAD_GRAYSCALE
- cvtColor(gt_2, gt_3, COLOR_GRAY2BGR); // For IMREAD_COLOR | IMREAD_ANYDEPTH
- if (gt.depth() == CV_16U)
- gt_3.convertTo(gt_1, CV_8U, 1. / 256);
- else
- gt_1 = gt_3; // For IMREAD_COLOR
- gt_256 = gt_1; // For IMREAD_COLOR_RGB
- gt_258 = gt_3; // For IMREAD_COLOR_RGB | IMREAD_ANYDEPTH
- }
- // Handle color images (3 or 4 channels) with 8-bit and 16-bit depth
- if (gt.channels() > 1)
- {
- // Convert to grayscale
- cvtColor(gt, gt_2, COLOR_BGRA2GRAY);
- if (gt.depth() == CV_16U)
- gt_2.convertTo(gt_0, CV_8U, 1. / 256);
- else
- gt_0 = gt_2;
- // Convert to 3-channel BGR
- if (gt.channels() == 3)
- gt.copyTo(gt_3);
- else
- cvtColor(gt, gt_3, COLOR_BGRA2BGR);
- if (gt.depth() == CV_16U)
- gt_3.convertTo(gt_1, CV_8U, 1. / 256);
- else
- gt_1 = gt_3;
- // Convert to RGB for IMREAD_COLOR_RGB variants
- cvtColor(gt_1, gt_256, COLOR_BGR2RGB);
- cvtColor(gt_3, gt_258, COLOR_BGR2RGB);
- }
- // Perform comparisons with different imread flags
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(1, 0), imread(filename, IMREAD_GRAYSCALE), gt_0);
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(1, 0), imread(filename, IMREAD_COLOR), gt_1);
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(4, 0), imread(filename, IMREAD_ANYDEPTH), gt_2);
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), imread(filename, IMREAD_COLOR | IMREAD_ANYDEPTH), gt_3);
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(1, 0), imread(filename, IMREAD_COLOR_RGB), gt_256);
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), imread(filename, IMREAD_COLOR_RGB | IMREAD_ANYDEPTH), gt_258);
- // Uncomment this block to write out the decoded images for visual/manual inspection
- // or for regenerating expected ground truth PNGs (for example, after changing decoder logic).
- #if 0
- imwrite(filename + "_0.png", imread(filename, IMREAD_GRAYSCALE));
- imwrite(filename + "_1.png", imread(filename, IMREAD_COLOR));
- imwrite(filename + "_2.png", imread(filename, IMREAD_ANYDEPTH));
- imwrite(filename + "_3.png", imread(filename, IMREAD_COLOR | IMREAD_ANYDEPTH));
- imwrite(filename + "_256.png", imread(filename, IMREAD_COLOR_RGB));
- imwrite(filename + "_258.png", imread(filename, IMREAD_COLOR_RGB | IMREAD_ANYDEPTH));
- #endif
- // Uncomment this block to verify that saved images (from above) load identically
- // when read back with IMREAD_UNCHANGED. Helps ensure write-read symmetry.
- #if 0
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), imread(filename, IMREAD_GRAYSCALE), imread(filename + "_0.png", IMREAD_UNCHANGED));
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), imread(filename, IMREAD_COLOR), imread(filename + "_1.png", IMREAD_UNCHANGED));
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), imread(filename, IMREAD_ANYDEPTH), imread(filename + "_2.png", IMREAD_UNCHANGED));
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), imread(filename, IMREAD_COLOR | IMREAD_ANYDEPTH), imread(filename + "_3.png", IMREAD_UNCHANGED));
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), imread(filename, IMREAD_COLOR_RGB), imread(filename + "_256.png", IMREAD_UNCHANGED));
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), imread(filename, IMREAD_COLOR_RGB | IMREAD_ANYDEPTH), imread(filename + "_258.png", IMREAD_UNCHANGED));
- #endif
- }
- const string pngsuite_files[] =
- {
- "basi0g01",
- "basi0g02",
- "basi0g04",
- "basi0g08",
- "basi0g16",
- "basi2c08",
- "basi2c16",
- "basi3p01",
- "basi3p02",
- "basi3p04",
- "basi3p08",
- "basi4a08",
- "basi4a16",
- "basi6a08",
- "basi6a16",
- "basn0g01",
- "basn0g02",
- "basn0g04",
- "basn0g08",
- "basn0g16",
- "basn2c08",
- "basn2c16",
- "basn3p01",
- "basn3p02",
- "basn3p04",
- "basn3p08",
- "basn4a08",
- "basn4a16",
- "basn6a08",
- "basn6a16",
- "bgai4a08",
- "bgai4a16",
- "bgan6a08",
- "bgan6a16",
- "bgbn4a08",
- "bggn4a16",
- "bgwn6a08",
- "bgyn6a16",
- "ccwn2c08",
- "ccwn3p08",
- "cdfn2c08",
- "cdhn2c08",
- "cdsn2c08",
- "cdun2c08",
- "ch1n3p04",
- "ch2n3p08",
- "cm0n0g04",
- "cm7n0g04",
- "cm9n0g04",
- "cs3n2c16",
- "cs3n3p08",
- "cs5n2c08",
- "cs5n3p08",
- "cs8n2c08",
- "cs8n3p08",
- "ct0n0g04",
- "ct1n0g04",
- "cten0g04",
- "ctfn0g04",
- "ctgn0g04",
- "cthn0g04",
- "ctjn0g04",
- "ctzn0g04",
- "exif2c08",
- "f00n0g08",
- "f00n2c08",
- "f01n0g08",
- "f01n2c08",
- "f02n0g08",
- "f02n2c08",
- "f03n0g08",
- "f03n2c08",
- "f04n0g08",
- "f04n2c08",
- "f99n0g04",
- "g03n0g16",
- "g04n0g16",
- "g05n0g16",
- "g07n0g16",
- "g10n0g16",
- "g10n2c08",
- "g10n3p04",
- "g25n0g16",
- "oi1n0g16",
- "oi1n2c16",
- "oi2n0g16",
- "oi2n2c16",
- "oi4n0g16",
- "oi4n2c16",
- "oi9n0g16",
- "oi9n2c16",
- "pp0n2c16",
- "pp0n6a08",
- "ps1n0g08",
- "ps1n2c16",
- "ps2n0g08",
- "ps2n2c16",
- "s01i3p01",
- "s01n3p01",
- "s02i3p01",
- "s02n3p01",
- "s03i3p01",
- "s03n3p01",
- "s04i3p01",
- "s04n3p01",
- "s05i3p02",
- "s05n3p02",
- "s06i3p02",
- "s06n3p02",
- "s07i3p02",
- "s07n3p02",
- "s08i3p02",
- "s08n3p02",
- "s09i3p02",
- "s09n3p02",
- "s32i3p04",
- "s32n3p04",
- "s33i3p04",
- "s33n3p04",
- "s34i3p04",
- "s34n3p04",
- "s35i3p04",
- "s35n3p04",
- "s36i3p04",
- "s36n3p04",
- "s37i3p04",
- "s37n3p04",
- "s38i3p04",
- "s38n3p04",
- "s39i3p04",
- "s39n3p04",
- "s40i3p04",
- "s40n3p04",
- "tbbn0g04",
- "tbbn2c16",
- "tbbn3p08",
- "tbgn2c16",
- "tbgn3p08",
- "tbrn2c08",
- "tbwn0g16",
- "tbwn3p08",
- "tbyn3p08",
- "tm3n3p02",
- "tp0n0g08",
- "tp0n2c08",
- "tp0n3p08",
- "tp1n3p08",
- "z00n2c08",
- "z03n2c08",
- "z06n2c08",
- "z09n2c08",
- };
- INSTANTIATE_TEST_CASE_P(/*nothing*/, Imgcodecs_Png_PngSuite,
- testing::ValuesIn(pngsuite_files));
- typedef testing::TestWithParam<string> Imgcodecs_Png_PngSuite_Gamma;
- // Parameterized test for decoding PNG files from the PNGSuite test set
- TEST_P(Imgcodecs_Png_PngSuite_Gamma, decode)
- {
- // Construct full paths for the PNG image and corresponding ground truth XML file
- const string root = cvtest::TS::ptr()->get_data_path();
- const string filename = root + "pngsuite/" + GetParam() + ".png";
- const string xml_filename = root + "pngsuite/" + GetParam() + ".xml";
- // Load the XML file containing the ground truth data
- FileStorage fs(xml_filename, FileStorage::READ);
- ASSERT_TRUE(fs.isOpened()); // Ensure the file was opened successfully
- // Load the image using IMREAD_UNCHANGED to preserve original format
- Mat src = imread(filename, IMREAD_UNCHANGED);
- ASSERT_FALSE(src.empty()); // Ensure the image was loaded successfully
- // Load the ground truth matrix from XML
- Mat gt;
- fs.getFirstTopLevelNode() >> gt;
- // Compare the image loaded with IMREAD_UNCHANGED to the ground truth
- EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), src, gt);
- }
- const string pngsuite_files_gamma[] =
- {
- "g03n2c08",
- "g03n3p04",
- "g04n2c08",
- "g04n3p04",
- "g05n2c08",
- "g05n3p04",
- "g07n2c08",
- "g07n3p04",
- "g25n2c08",
- "g25n3p04"
- };
- INSTANTIATE_TEST_CASE_P(/*nothing*/, Imgcodecs_Png_PngSuite_Gamma,
- testing::ValuesIn(pngsuite_files_gamma));
- typedef testing::TestWithParam<string> Imgcodecs_Png_PngSuite_Corrupted;
- TEST_P(Imgcodecs_Png_PngSuite_Corrupted, decode)
- {
- const string root = cvtest::TS::ptr()->get_data_path();
- const string filename = root + "pngsuite/" + GetParam() + ".png";
- Mat src = imread(filename, IMREAD_UNCHANGED);
- // Corrupted files should not be read
- EXPECT_TRUE(src.empty());
- }
- const string pngsuite_files_corrupted[] = {
- "xc1n0g08",
- "xc9n2c08",
- "xcrn0g04",
- "xcsn0g01",
- "xd0n2c08",
- "xd3n2c08",
- "xd9n2c08",
- "xdtn0g01",
- "xhdn0g08",
- "xlfn0g04",
- "xs1n0g01",
- "xs2n0g01",
- "xs4n0g01",
- "xs7n0g01",
- };
- INSTANTIATE_TEST_CASE_P(/*nothing*/, Imgcodecs_Png_PngSuite_Corrupted,
- testing::ValuesIn(pngsuite_files_corrupted));
- CV_ENUM(PNGStrategy, IMWRITE_PNG_STRATEGY_DEFAULT, IMWRITE_PNG_STRATEGY_FILTERED, IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY, IMWRITE_PNG_STRATEGY_RLE, IMWRITE_PNG_STRATEGY_FIXED);
- CV_ENUM(PNGFilters, IMWRITE_PNG_FILTER_NONE, IMWRITE_PNG_FILTER_SUB, IMWRITE_PNG_FILTER_UP, IMWRITE_PNG_FILTER_AVG, IMWRITE_PNG_FILTER_PAETH, IMWRITE_PNG_FAST_FILTERS, IMWRITE_PNG_ALL_FILTERS);
- typedef testing::TestWithParam<testing::tuple<string, PNGStrategy, PNGFilters, int>> Imgcodecs_Png_Encode;
- TEST_P(Imgcodecs_Png_Encode, params)
- {
- const string root = cvtest::TS::ptr()->get_data_path();
- const string filename = root + "pngsuite/" + get<0>(GetParam());
- const int strategy = get<1>(GetParam());
- const int filter = get<2>(GetParam());
- const int compression_level = get<3>(GetParam());
- std::vector<uchar> file_buf;
- readFileBytes(filename, file_buf);
- Mat src = imdecode(file_buf, IMREAD_UNCHANGED);
- EXPECT_FALSE(src.empty()) << "Cannot decode test image " << filename;
- vector<uchar> buf;
- imencode(".png", src, buf, { IMWRITE_PNG_COMPRESSION, compression_level, IMWRITE_PNG_STRATEGY, strategy, IMWRITE_PNG_FILTER, filter });
- EXPECT_EQ(buf.size(), file_buf.size());
- }
- INSTANTIATE_TEST_CASE_P(/**/,
- Imgcodecs_Png_Encode,
- testing::Values(
- make_tuple("f00n0g08.png", IMWRITE_PNG_STRATEGY_DEFAULT, IMWRITE_PNG_FILTER_NONE, 6),
- make_tuple("f00n2c08.png", IMWRITE_PNG_STRATEGY_DEFAULT, IMWRITE_PNG_FILTER_NONE, 6),
- make_tuple("f01n0g08.png", IMWRITE_PNG_STRATEGY_FILTERED, IMWRITE_PNG_FILTER_SUB, 6),
- make_tuple("f01n2c08.png", IMWRITE_PNG_STRATEGY_FILTERED, IMWRITE_PNG_FILTER_SUB, 6),
- make_tuple("f02n0g08.png", IMWRITE_PNG_STRATEGY_FILTERED, IMWRITE_PNG_FILTER_UP, 6),
- make_tuple("f02n2c08.png", IMWRITE_PNG_STRATEGY_FILTERED, IMWRITE_PNG_FILTER_UP, 6),
- make_tuple("f03n0g08.png", IMWRITE_PNG_STRATEGY_FILTERED, IMWRITE_PNG_FILTER_AVG, 6),
- make_tuple("f03n2c08.png", IMWRITE_PNG_STRATEGY_FILTERED, IMWRITE_PNG_FILTER_AVG, 6),
- make_tuple("f04n0g08.png", IMWRITE_PNG_STRATEGY_FILTERED, IMWRITE_PNG_FILTER_PAETH, 6),
- make_tuple("f04n2c08.png", IMWRITE_PNG_STRATEGY_FILTERED, IMWRITE_PNG_FILTER_PAETH, 6),
- make_tuple("z03n2c08.png", IMWRITE_PNG_STRATEGY_FILTERED, IMWRITE_PNG_ALL_FILTERS, 3),
- make_tuple("z06n2c08.png", IMWRITE_PNG_STRATEGY_FILTERED, IMWRITE_PNG_ALL_FILTERS, 6),
- make_tuple("z09n2c08.png", IMWRITE_PNG_STRATEGY_FILTERED, IMWRITE_PNG_ALL_FILTERS, 9)));
- typedef testing::TestWithParam<testing::tuple<string, int, size_t>> Imgcodecs_Png_ImwriteFlags;
- TEST_P(Imgcodecs_Png_ImwriteFlags, compression_level)
- {
- const string root = cvtest::TS::ptr()->get_data_path();
- const string filename = root + get<0>(GetParam());
- const int compression_level = get<1>(GetParam());
- const size_t compression_level_output_size = get<2>(GetParam());
- Mat src = imread(filename, IMREAD_UNCHANGED);
- EXPECT_FALSE(src.empty()) << "Cannot read test image " << filename;
- vector<uchar> buf;
- imencode(".png", src, buf, { IMWRITE_PNG_COMPRESSION, compression_level });
- EXPECT_EQ(buf.size(), compression_level_output_size);
- }
- INSTANTIATE_TEST_CASE_P(/**/,
- Imgcodecs_Png_ImwriteFlags,
- testing::Values(
- make_tuple("../perf/512x512.png", 0, 788279),
- make_tuple("../perf/512x512.png", 1, 179503),
- make_tuple("../perf/512x512.png", 2, 176007),
- make_tuple("../perf/512x512.png", 3, 170497),
- make_tuple("../perf/512x512.png", 4, 163357),
- make_tuple("../perf/512x512.png", 5, 159190),
- make_tuple("../perf/512x512.png", 6, 156621),
- make_tuple("../perf/512x512.png", 7, 155696),
- make_tuple("../perf/512x512.png", 8, 153708),
- make_tuple("../perf/512x512.png", 9, 152181)));
- // See https://github.com/opencv/opencv/issues/27614
- typedef testing::TestWithParam<int> Imgcodecs_Png_ZLIBBUFFER_SIZE;
- TEST_P(Imgcodecs_Png_ZLIBBUFFER_SIZE, encode_regression_27614)
- {
- Mat img(320,240,CV_8UC3,cv::Scalar(64,76,43));
- vector<uint8_t> buff;
- bool status = false;
- ASSERT_NO_THROW(status = imencode(".png", img, buff, { IMWRITE_PNG_ZLIBBUFFER_SIZE, GetParam() }));
- ASSERT_TRUE(status);
- }
- INSTANTIATE_TEST_CASE_P(/*nothing*/, Imgcodecs_Png_ZLIBBUFFER_SIZE,
- testing::Values(5,
- 6, // Minimum limit
- 8192, // Default value
- 131072, // 128 KiB
- 262144, // 256 KiB
- 1048576, // Maximum limit
- 1048577));
- #endif // HAVE_PNG
- }} // namespace
|