From dac243bd265e79af2315ce04fac2a0a5bdf47efe Mon Sep 17 00:00:00 2001 From: Kumataro Date: Thu, 11 Sep 2025 22:50:58 +0900 Subject: [PATCH] Merge pull request #27769 from Kumataro:refix27557 Add strict validation for encoding parameters for APNG, Animation WebP #27769 Extra fix for https://github.com/opencv/opencv/issues/27557 - Fix for build errors with libspng library. - Add strict validation for APNG. - Add strict validation for Animation WebP. ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- .../imgcodecs/include/opencv2/imgcodecs.hpp | 6 +- modules/imgcodecs/src/grfmt_png.cpp | 56 +++++++++++++++---- modules/imgcodecs/src/grfmt_spng.cpp | 6 +- modules/imgcodecs/src/grfmt_webp.cpp | 17 +++--- 4 files changed, 60 insertions(+), 25 deletions(-) diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index eaf62c561f..9f6b7b6fcd 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -95,9 +95,9 @@ enum ImwriteFlags { 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, //!< 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 with libpng, sets the size of the internal zlib compression buffer in bytes, from 6 to 1048576(1024 KiB). Default is 8192(8 KiB). For normal use, 131072(128 KiB) or 262144(256 KiB) may be sufficient. If WITH_SPNG=ON, it is not supported. + IMWRITE_PNG_BILEVEL = 18, //!< For PNG, Binary level PNG, 0 or 1, default is 0. For APNG, it is not supported. + IMWRITE_PNG_FILTER = 19, //!< For PNG, One of cv::ImwritePNGFilterFlags, default is IMWRITE_PNG_FILTER_SUB. For APNG, it is not supported. + IMWRITE_PNG_ZLIBBUFFER_SIZE = 20, //!< For PNG with libpng, sets the size of the internal zlib compression buffer in bytes, from 6 to 1048576(1024 KiB). Default is 8192(8 KiB). For normal use, 131072(128 KiB) or 262144(256 KiB) may be sufficient. If WITH_SPNG=ON, it is not supported. For APNG, it is not supported. 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 e4d9a5d02c..dbb3c41cf2 100644 --- a/modules/imgcodecs/src/grfmt_png.cpp +++ b/modules/imgcodecs/src/grfmt_png.cpp @@ -1630,20 +1630,52 @@ bool PngEncoder::writeanimation(const Animation& animation, const std::vector ¶ms) { compression_strategy = IMWRITE_PNG_STRATEGY_DEFAULT; // Default strategy compression_level = MIN(MAX(value, 0), Z_BEST_COMPRESSION); - if(value != m_compression_level) { - CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_COMPRESSION must be between 0 to 9. It is fallbacked to %d", value, m_compression_level)); + if(value != compression_level) { + CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_COMPRESSION must be between 0 to 9. It is fallbacked to %d", value, compression_level)); } set_compression_level = true; } @@ -556,7 +556,7 @@ bool SPngEncoder::write(const Mat &img, const std::vector ¶ms) compression_strategy = value; break; default: - compression_strategy = IMWRITE_PNG_STRATEGY_RLE: + compression_strategy = IMWRITE_PNG_STRATEGY_RLE; CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_STRATEGY must be one of ImwritePNGFlags. It is fallbacked to IMWRITE_PNG_STRATEGY_RLE", value)); break; } diff --git a/modules/imgcodecs/src/grfmt_webp.cpp b/modules/imgcodecs/src/grfmt_webp.cpp index ae11c7ce2c..932f08bec1 100644 --- a/modules/imgcodecs/src/grfmt_webp.cpp +++ b/modules/imgcodecs/src/grfmt_webp.cpp @@ -511,23 +511,26 @@ bool WebPEncoder::writeanimation(const Animation& animation, const std::vector 1) + for(size_t i = 0; i < params.size(); i += 2) { - if (params[0] == IMWRITE_WEBP_QUALITY) + const int value = params[i+1]; + if (params[i] == IMWRITE_WEBP_QUALITY) { - config.lossless = 0; - config.quality = static_cast(params[1]); + config.lossless = 0; // false + config.quality = static_cast(value); if (config.quality < 1.0f) { config.quality = 1.0f; + CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_WEBP_QUALITY must be between 1 to 100(lossy) or more(lossless). It is fallbacked to 1", value)); } - if (config.quality >= 100.0f) + if (config.quality > 100.0f) { - config.lossless = 1; + config.quality = 100.0f; + config.lossless = 1; // true } } - anim_config.minimize_size = 0; } std::unique_ptr anim_encoder(