diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index 14d562c823..d102c5c9c7 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -94,9 +94,10 @@ enum ImwriteFlags { IMWRITE_JPEG_CHROMA_QUALITY = 6, //!< Separate chroma quality level, 0 - 100, default is -1 - don't use. If JPEG_LIB_VERSION < 70, Not supported. IMWRITE_JPEG_SAMPLING_FACTOR = 7, //!< For JPEG, set sampling factor. See cv::ImwriteJPEGSamplingFactorParams. IMWRITE_PNG_COMPRESSION = 16, //!< For PNG, it can be the compression level from 0 to 9. A higher value means a smaller size and longer compression time. If specified, strategy is changed to IMWRITE_PNG_STRATEGY_DEFAULT (Z_DEFAULT_STRATEGY). Default value is 1 (best speed setting). - IMWRITE_PNG_STRATEGY = 17, //!< One of cv::ImwritePNGFlags, default is IMWRITE_PNG_STRATEGY_RLE. - IMWRITE_PNG_BILEVEL = 18, //!< Binary level PNG, 0 or 1, default is 0. - IMWRITE_PNG_FILTER = 19, //!< One of cv::ImwritePNGFilterFlags, default is IMWRITE_PNG_FILTER_SUB. + IMWRITE_PNG_STRATEGY = 17, //!< For PNG, One of cv::ImwritePNGFlags, default is IMWRITE_PNG_STRATEGY_RLE. + IMWRITE_PNG_BILEVEL = 18, //!< For PNG, Binary level PNG, 0 or 1, default is 0. + IMWRITE_PNG_FILTER = 19, //!< For PNG, One of cv::ImwritePNGFilterFlags, default is IMWRITE_PNG_FILTER_SUB. + IMWRITE_PNG_ZLIBBUFFER_SIZE = 20, //!< For PNG, sets the size of the internal zlib compression buffer in bytes. IMWRITE_PXM_BINARY = 32, //!< For PPM, PGM, or PBM, it can be a binary format flag, 0 or 1. Default value is 1. IMWRITE_EXR_TYPE = (3 << 4) + 0 /* 48 */, //!< override EXR storage type (FLOAT (FP32) is default) IMWRITE_EXR_COMPRESSION = (3 << 4) + 1 /* 49 */, //!< override EXR compression type (ZIP_COMPRESSION = 3 is default) diff --git a/modules/imgcodecs/src/grfmt_png.cpp b/modules/imgcodecs/src/grfmt_png.cpp index c78c0efc55..903ae2475b 100644 --- a/modules/imgcodecs/src/grfmt_png.cpp +++ b/modules/imgcodecs/src/grfmt_png.cpp @@ -947,26 +947,36 @@ bool PngEncoder::write( const Mat& img, const std::vector& params ) for( size_t i = 0; i < params.size(); i += 2 ) { - if( params[i] == IMWRITE_PNG_COMPRESSION ) + switch (params[i]) { + case IMWRITE_PNG_COMPRESSION: m_compression_strategy = IMWRITE_PNG_STRATEGY_DEFAULT; // Default strategy m_compression_level = params[i+1]; m_compression_level = MIN(MAX(m_compression_level, 0), Z_BEST_COMPRESSION); set_compression_level = true; - } - if( params[i] == IMWRITE_PNG_STRATEGY ) - { + break; + + case IMWRITE_PNG_STRATEGY: m_compression_strategy = params[i+1]; m_compression_strategy = MIN(MAX(m_compression_strategy, 0), Z_FIXED); - } - if( params[i] == IMWRITE_PNG_BILEVEL ) - { + break; + + case IMWRITE_PNG_BILEVEL: m_isBilevel = params[i+1] != 0; - } - if( params[i] == IMWRITE_PNG_FILTER ) - { + break; + + case IMWRITE_PNG_FILTER: m_filter = params[i+1]; set_filter = true; + break; + + case IMWRITE_PNG_ZLIBBUFFER_SIZE: + png_set_compression_buffer_size(png_ptr, params[i+1]); + break; + + default: + CV_LOG_WARNING(NULL, "An unknown or unsupported ImwriteFlags value was specified and has been ignored."); + break; } } diff --git a/modules/imgcodecs/test/test_png.cpp b/modules/imgcodecs/test/test_png.cpp index 583039202a..a1a743ee0f 100644 --- a/modules/imgcodecs/test/test_png.cpp +++ b/modules/imgcodecs/test/test_png.cpp @@ -12,14 +12,15 @@ TEST(Imgcodecs_Png, write_big) { const string root = cvtest::TS::ptr()->get_data_path(); const string filename = root + "readwrite/read.png"; - const string dst_file = cv::tempfile(".png"); Mat img; ASSERT_NO_THROW(img = imread(filename)); ASSERT_FALSE(img.empty()); EXPECT_EQ(13043, img.cols); EXPECT_EQ(13917, img.rows); - ASSERT_NO_THROW(imwrite(dst_file, img)); - EXPECT_EQ(0, remove(dst_file.c_str())); + + vector buff; + ASSERT_NO_THROW(imencode(".png", img, buff, { IMWRITE_PNG_ZLIBBUFFER_SIZE, INT_MAX })); + EXPECT_EQ((size_t)816219, buff.size()); } TEST(Imgcodecs_Png, encode)