diff --git a/.gitignore b/.gitignore index 737beee..248de94 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,3 @@ face_landmark_model.dat.xz /fa4b3e25167319cb0fa9432ef8281945-v0.1.2a.zip /wechat-20230712.git3487ef7.tar.gz /dbb095a8bf3008e91edbbf45d8d34885-v0.1.2d.zip -/962ce79e0b95591f226431f7b5f152cd-v0.1.2e.zip diff --git a/.packit.yaml b/.packit.yaml index 85e1cb2..53d233b 100644 --- a/.packit.yaml +++ b/.packit.yaml @@ -1,19 +1,17 @@ # See the documentation for more information: # https://packit.dev/docs/configuration/ +upstream_project_url: https://github.com/opencv/opencv + # run opencv-clean.sh # the sed currently hacks the script so that the version is correctly set and the sources upload is handled by Packit actions: pre-sync: - - bash -c "${PACKIT_DOWNSTREAM_REPO}/opencv-clean.sh ${PACKIT_PROJECT_VERSION}" - -files_to_sync: - - src: - - "opencv*clean-*.tar.gz" - dest: . + - bash -c "cd ${PACKIT_DOWNSTREAM_REPO}; sed '3d;$d' ./opencv-clean.sh | VERSION=${PACKIT_PROJECT_VERSION} bash" jobs: - job: pull_from_upstream trigger: release dist_git_branches: - fedora-rawhide + diff --git a/0001-Merge-pull-request-26739-from-vrabaud-png_leak.patch b/0001-Merge-pull-request-26739-from-vrabaud-png_leak.patch deleted file mode 100644 index a24eff9..0000000 --- a/0001-Merge-pull-request-26739-from-vrabaud-png_leak.patch +++ /dev/null @@ -1,155 +0,0 @@ -From c399203e9861bf3ff5b976cd597b9820eee5d93a Mon Sep 17 00:00:00 2001 -From: Vincent Rabaud -Date: Fri, 10 Jan 2025 09:33:43 +0100 -Subject: [PATCH 01/10] Merge pull request #26739 from vrabaud:png_leak - -Add more boundary checks. #26739 - -Also fix a bug in read_chunk where we could end up with png_get_uint_32(len) + 12 < 4 - -### 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 -- [ ] 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. -- [ ] The feature is well documented and sample code can be built with the project CMake ---- - modules/imgcodecs/src/grfmt_png.cpp | 54 +++++++++++++++++------------ - modules/imgcodecs/src/grfmt_png.hpp | 2 +- - 2 files changed, 33 insertions(+), 23 deletions(-) - -diff --git a/modules/imgcodecs/src/grfmt_png.cpp b/modules/imgcodecs/src/grfmt_png.cpp -index 6b4cea405c..744f244a20 100644 ---- a/modules/imgcodecs/src/grfmt_png.cpp -+++ b/modules/imgcodecs/src/grfmt_png.cpp -@@ -255,11 +255,14 @@ bool PngDecoder::readHeader() - png_init_io(png_ptr, m_f); - } - -- if (read_from_io(&sig, 8, 1) != 1) -+ // Read PNG header: 137 80 78 71 13 10 26 10 -+ if (!read_from_io(&sig, 8)) - return false; - - id = read_chunk(m_chunkIHDR); -- if (!(id == id_IHDR && m_chunkIHDR.p.size() == 25)) -+ // 8=HDR+size, 13=size of IHDR chunk, 4=CRC -+ // http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.IHDR -+ if (!(id == id_IHDR && m_chunkIHDR.p.size() == 8 + 13 + 4)) - { - return false; - } -@@ -283,23 +286,25 @@ bool PngDecoder::readHeader() - break; - } - -- if (id == id_acTL && chunk.p.size() == 20) -+ if (id == id_acTL) - { -+ // 8=HDR+size, 8=size of acTL chunk, 4=CRC -+ // https://wiki.mozilla.org/APNG_Specification#%60acTL%60:_The_Animation_Control_Chunk -+ if (chunk.p.size() != 8 + 8 + 4) -+ return false; - m_animation.loop_count = png_get_uint_32(&chunk.p[12]); - -- if (chunk.p[8] > 0) -- { -- chunk.p[8] = 0; -- chunk.p[9] = 0; -- m_frame_count = png_get_uint_32(&chunk.p[8]); -- m_frame_count++; -- } -- else -- m_frame_count = png_get_uint_32(&chunk.p[8]); -+ m_frame_count = png_get_uint_32(&chunk.p[8]); -+ if (m_frame_count == 0) -+ return false; - } - - if (id == id_fcTL) - { -+ // 8=HDR+size, 26=size of fcTL chunk, 4=CRC -+ // https://wiki.mozilla.org/APNG_Specification#%60fcTL%60:_The_Frame_Control_Chunk -+ if (chunk.p.size() != 8 + 26 + 4) -+ return false; - m_is_fcTL_loaded = true; - w0 = png_get_uint_32(&chunk.p[12]); - h0 = png_get_uint_32(&chunk.p[16]); -@@ -313,6 +318,11 @@ bool PngDecoder::readHeader() - - if (id == id_bKGD) - { -+ // 8=HDR+size, ??=size of bKGD chunk, 4=CRC -+ // The spec is actually more complex: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.bKGD -+ // TODO: we only check that 4 bytes can be read from &chunk.p[8]. Fix. -+ if (chunk.p.size() < 8 + 4) -+ return false; - int bgcolor = png_get_uint_32(&chunk.p[8]); - m_animation.bgcolor[3] = (bgcolor >> 24) & 0xFF; - m_animation.bgcolor[2] = (bgcolor >> 16) & 0xFF; -@@ -669,34 +679,34 @@ void PngDecoder::compose_frame(std::vector& rows_dst, const std::vect - }); - } - --size_t PngDecoder::read_from_io(void* _Buffer, size_t _ElementSize, size_t _ElementCount) -+bool PngDecoder::read_from_io(void* buffer, size_t num_bytes) - { - if (m_f) -- return fread(_Buffer, _ElementSize, _ElementCount, m_f); -+ return fread(buffer, 1, num_bytes, m_f) == num_bytes; - -- if (m_buf_pos + _ElementSize > m_buf.cols * m_buf.rows * m_buf.elemSize()) { -+ if (m_buf_pos + num_bytes > m_buf.cols * m_buf.rows * m_buf.elemSize()) { - CV_LOG_WARNING(NULL, "PNG input buffer is incomplete"); -- return 0; -+ return false; - } - -- memcpy( _Buffer, m_buf.ptr() + m_buf_pos, _ElementSize ); -- m_buf_pos += _ElementSize; -- return 1; -+ memcpy( buffer, m_buf.ptr() + m_buf_pos, num_bytes ); -+ m_buf_pos += num_bytes; -+ return true; - } - - uint32_t PngDecoder::read_chunk(Chunk& chunk) - { - unsigned char len[4]; -- if (read_from_io(&len, 4, 1) == 1) -+ if (read_from_io(&len, 4)) - { -- const size_t size = png_get_uint_32(len) + 12; -+ const size_t size = static_cast(png_get_uint_32(len)) + 12; - if (size > PNG_USER_CHUNK_MALLOC_MAX) - { - CV_LOG_WARNING(NULL, "chunk data is too large"); - } - chunk.p.resize(size); - memcpy(chunk.p.data(), len, 4); -- if (read_from_io(&chunk.p[4], chunk.p.size() - 4, 1) == 1) -+ if (read_from_io(&chunk.p[4], chunk.p.size() - 4)) - return *(uint32_t*)(&chunk.p[4]); - } - return 0; -diff --git a/modules/imgcodecs/src/grfmt_png.hpp b/modules/imgcodecs/src/grfmt_png.hpp -index a950b9e941..dec2cd0b61 100644 ---- a/modules/imgcodecs/src/grfmt_png.hpp -+++ b/modules/imgcodecs/src/grfmt_png.hpp -@@ -137,7 +137,7 @@ protected: - bool processing_start(void* frame_ptr, const Mat& img); - bool processing_finish(); - void compose_frame(std::vector& rows_dst, const std::vector& rows_src, unsigned char bop, uint32_t x, uint32_t y, uint32_t w, uint32_t h, Mat& img); -- size_t read_from_io(void* _Buffer, size_t _ElementSize, size_t _ElementCount); -+ bool read_from_io(void* buffer, size_t num_bytes); - uint32_t read_chunk(Chunk& chunk); - - struct PngPtrs { --- -2.48.1 - diff --git a/0002-Fix-remaining-bugs-in-PNG-reader.patch b/0002-Fix-remaining-bugs-in-PNG-reader.patch deleted file mode 100644 index f4804e6..0000000 --- a/0002-Fix-remaining-bugs-in-PNG-reader.patch +++ /dev/null @@ -1,37 +0,0 @@ -From b7b84ec6364809306776b48206ad36266274c297 Mon Sep 17 00:00:00 2001 -From: Vincent Rabaud -Date: Fri, 10 Jan 2025 14:57:39 +0100 -Subject: [PATCH 02/10] Fix remaining bugs in PNG reader - -- free chunk before a potential longjmp -- do not try to allocate when the chunk is > PNG_USER_CHUNK_MALLOC_MAX ---- - modules/imgcodecs/src/grfmt_png.cpp | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/modules/imgcodecs/src/grfmt_png.cpp b/modules/imgcodecs/src/grfmt_png.cpp -index 744f244a20..1ecc01f17f 100644 ---- a/modules/imgcodecs/src/grfmt_png.cpp -+++ b/modules/imgcodecs/src/grfmt_png.cpp -@@ -339,6 +339,10 @@ bool PngDecoder::readHeader() - png_bytep trans; - png_color_16p trans_values; - -+ // Free chunk in case png_read_info uses longjmp. -+ chunk.p.clear(); -+ chunk.p.shrink_to_fit(); -+ - png_read_info( png_ptr, info_ptr ); - png_get_IHDR(png_ptr, info_ptr, &wdth, &hght, - &bit_depth, &color_type, 0, 0, 0); -@@ -703,6 +707,7 @@ uint32_t PngDecoder::read_chunk(Chunk& chunk) - if (size > PNG_USER_CHUNK_MALLOC_MAX) - { - CV_LOG_WARNING(NULL, "chunk data is too large"); -+ return 0; - } - chunk.p.resize(size); - memcpy(chunk.p.data(), len, 4); --- -2.48.1 - diff --git a/0003-Merge-pull-request-26782-from-vrabaud-png_leak.patch b/0003-Merge-pull-request-26782-from-vrabaud-png_leak.patch deleted file mode 100644 index 9d11730..0000000 --- a/0003-Merge-pull-request-26782-from-vrabaud-png_leak.patch +++ /dev/null @@ -1,654 +0,0 @@ -From c29de7cc4b89c80f7ee910f318dfc1bc462d576c Mon Sep 17 00:00:00 2001 -From: Vincent Rabaud -Date: Wed, 22 Jan 2025 12:47:28 +0100 -Subject: [PATCH 03/10] Merge pull request #26782 from vrabaud:png_leak - -Fix potential READ memory access #26782 - -This fixes https://oss-fuzz.com/testcase-detail/4923671881252864 and https://oss-fuzz.com/testcase-detail/5048650127966208 - -### 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. -- [ ] The feature is well documented and sample code can be built with the project CMake ---- - modules/imgcodecs/src/grfmt_png.cpp | 394 ++++++++++++++-------------- - modules/imgcodecs/src/grfmt_png.hpp | 53 +--- - 2 files changed, 206 insertions(+), 241 deletions(-) - -diff --git a/modules/imgcodecs/src/grfmt_png.cpp b/modules/imgcodecs/src/grfmt_png.cpp -index 1ecc01f17f..105288c5e5 100644 ---- a/modules/imgcodecs/src/grfmt_png.cpp -+++ b/modules/imgcodecs/src/grfmt_png.cpp -@@ -198,6 +198,7 @@ PngDecoder::PngDecoder() - - PngDecoder::~PngDecoder() - { -+ ClearPngPtr(); - if( m_f ) - { - fclose( m_f ); -@@ -205,6 +206,26 @@ PngDecoder::~PngDecoder() - } - } - -+bool PngDecoder::InitPngPtr() { -+ ClearPngPtr(); -+ -+ m_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); -+ if (!m_png_ptr) -+ return false; -+ -+ m_info_ptr = png_create_info_struct(m_png_ptr); -+ m_end_info = png_create_info_struct(m_png_ptr); -+ return (m_info_ptr && m_end_info); -+} -+ -+void PngDecoder::ClearPngPtr() { -+ if (m_png_ptr) -+ png_destroy_read_struct(&m_png_ptr, &m_info_ptr, &m_end_info); -+ m_png_ptr = nullptr; -+ m_info_ptr = nullptr; -+ m_end_info = nullptr; -+} -+ - ImageDecoder PngDecoder::newDecoder() const - { - return makePtr(); -@@ -227,167 +248,164 @@ void PngDecoder::readDataFromBuf( void* _png_ptr, unsigned char* dst, size_t si - - bool PngDecoder::readHeader() - { -- volatile bool result = false; -+ // Declare dynamic variables before a potential longjmp. -+ Chunk chunk; -+ -+ if (!InitPngPtr()) -+ return false; -+ -+ if (setjmp(png_jmpbuf(m_png_ptr))) -+ return false; - -- PngPtrs png_ptrs; -- png_structp png_ptr = png_ptrs.getPng(); -- png_infop info_ptr = png_ptrs.getInfo(); -- png_infop end_info = png_ptrs.getEndInfo(); -+ m_buf_pos = 0; -+ unsigned char sig[8]; -+ uint32_t id = 0; - -- if( png_ptr && info_ptr && end_info ) -+ if( !m_buf.empty() ) -+ png_set_read_fn(m_png_ptr, this, (png_rw_ptr)readDataFromBuf ); -+ else - { -- m_buf_pos = 0; -- if( setjmp( png_jmpbuf( png_ptr ) ) == 0 ) -+ m_f = fopen(m_filename.c_str(), "rb"); -+ if (!m_f) - { -- unsigned char sig[8]; -- uint32_t id = 0; -- Chunk chunk; -+ return false; -+ } -+ png_init_io(m_png_ptr, m_f); -+ } - -- if( !m_buf.empty() ) -- png_set_read_fn(png_ptr, this, (png_rw_ptr)readDataFromBuf ); -- else -- { -- m_f = fopen(m_filename.c_str(), "rb"); -- if (!m_f) -- { -- return false; -- } -- png_init_io(png_ptr, m_f); -- } -+ // Read PNG header: 137 80 78 71 13 10 26 10 -+ if (!read_from_io(&sig, 8)) -+ return false; - -- // Read PNG header: 137 80 78 71 13 10 26 10 -- if (!read_from_io(&sig, 8)) -- return false; -+ id = read_chunk(m_chunkIHDR); -+ // 8=HDR+size, 13=size of IHDR chunk, 4=CRC -+ // http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.IHDR -+ if (!(id == id_IHDR && m_chunkIHDR.p.size() == 8 + 13 + 4)) -+ { -+ return false; -+ } - -- id = read_chunk(m_chunkIHDR); -- // 8=HDR+size, 13=size of IHDR chunk, 4=CRC -- // http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.IHDR -- if (!(id == id_IHDR && m_chunkIHDR.p.size() == 8 + 13 + 4)) -- { -- return false; -- } -+ m_is_fcTL_loaded = false; -+ while (true) -+ { -+ id = read_chunk(chunk); - -- while (true) -- { -- m_is_fcTL_loaded = false; -- id = read_chunk(chunk); -+ if (!id || (m_f && feof(m_f)) || (!m_buf.empty() && m_buf_pos > m_buf.total())) -+ { -+ return false; -+ } - -- if (!id || (m_f && feof(m_f)) || (!m_buf.empty() && m_buf_pos > m_buf.total())) -- { -- return false; -- } -+ if (id == id_IDAT) -+ { -+ if (m_f) -+ fseek(m_f, 0, SEEK_SET); -+ else -+ m_buf_pos = 0; -+ break; -+ } - -- if (id == id_IDAT) -- { -- if (m_f) -- fseek(m_f, 0, SEEK_SET); -- else -- m_buf_pos = 0; -- break; -- } -+ if (id == id_acTL) -+ { -+ // 8=HDR+size, 8=size of acTL chunk, 4=CRC -+ // https://wiki.mozilla.org/APNG_Specification#%60acTL%60:_The_Animation_Control_Chunk -+ if (chunk.p.size() != 8 + 8 + 4) -+ return false; -+ m_animation.loop_count = png_get_uint_32(&chunk.p[12]); - -- if (id == id_acTL) -- { -- // 8=HDR+size, 8=size of acTL chunk, 4=CRC -- // https://wiki.mozilla.org/APNG_Specification#%60acTL%60:_The_Animation_Control_Chunk -- if (chunk.p.size() != 8 + 8 + 4) -- return false; -- m_animation.loop_count = png_get_uint_32(&chunk.p[12]); -- -- m_frame_count = png_get_uint_32(&chunk.p[8]); -- if (m_frame_count == 0) -- return false; -- } -+ m_frame_count = png_get_uint_32(&chunk.p[8]); -+ if (m_frame_count == 0) -+ return false; -+ } - -- if (id == id_fcTL) -- { -- // 8=HDR+size, 26=size of fcTL chunk, 4=CRC -- // https://wiki.mozilla.org/APNG_Specification#%60fcTL%60:_The_Frame_Control_Chunk -- if (chunk.p.size() != 8 + 26 + 4) -- return false; -- m_is_fcTL_loaded = true; -- w0 = png_get_uint_32(&chunk.p[12]); -- h0 = png_get_uint_32(&chunk.p[16]); -- x0 = png_get_uint_32(&chunk.p[20]); -- y0 = png_get_uint_32(&chunk.p[24]); -- delay_num = png_get_uint_16(&chunk.p[28]); -- delay_den = png_get_uint_16(&chunk.p[30]); -- dop = chunk.p[32]; -- bop = chunk.p[33]; -- } -+ if (id == id_fcTL) -+ { -+ // 8=HDR+size, 26=size of fcTL chunk, 4=CRC -+ // https://wiki.mozilla.org/APNG_Specification#%60fcTL%60:_The_Frame_Control_Chunk -+ if (chunk.p.size() != 8 + 26 + 4) -+ return false; -+ m_is_fcTL_loaded = true; -+ w0 = png_get_uint_32(&chunk.p[12]); -+ h0 = png_get_uint_32(&chunk.p[16]); -+ x0 = png_get_uint_32(&chunk.p[20]); -+ y0 = png_get_uint_32(&chunk.p[24]); -+ delay_num = png_get_uint_16(&chunk.p[28]); -+ delay_den = png_get_uint_16(&chunk.p[30]); -+ dop = chunk.p[32]; -+ bop = chunk.p[33]; -+ } - -- if (id == id_bKGD) -- { -- // 8=HDR+size, ??=size of bKGD chunk, 4=CRC -- // The spec is actually more complex: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.bKGD -- // TODO: we only check that 4 bytes can be read from &chunk.p[8]. Fix. -- if (chunk.p.size() < 8 + 4) -- return false; -- int bgcolor = png_get_uint_32(&chunk.p[8]); -- m_animation.bgcolor[3] = (bgcolor >> 24) & 0xFF; -- m_animation.bgcolor[2] = (bgcolor >> 16) & 0xFF; -- m_animation.bgcolor[1] = (bgcolor >> 8) & 0xFF; -- m_animation.bgcolor[0] = bgcolor & 0xFF; -- } -+ if (id == id_bKGD) -+ { -+ // 8=HDR+size, ??=size of bKGD chunk, 4=CRC -+ // The spec is actually more complex: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.bKGD -+ // TODO: we only check that 4 bytes can be read from &chunk.p[8]. Fix. -+ if (chunk.p.size() < 8 + 4) -+ return false; -+ int bgcolor = png_get_uint_32(&chunk.p[8]); -+ m_animation.bgcolor[3] = (bgcolor >> 24) & 0xFF; -+ m_animation.bgcolor[2] = (bgcolor >> 16) & 0xFF; -+ m_animation.bgcolor[1] = (bgcolor >> 8) & 0xFF; -+ m_animation.bgcolor[0] = bgcolor & 0xFF; -+ } - -- if (id == id_PLTE || id == id_tRNS) -- m_chunksInfo.push_back(chunk); -- } -+ if (id == id_PLTE || id == id_tRNS) -+ m_chunksInfo.push_back(chunk); -+ } - -- png_uint_32 wdth, hght; -- int bit_depth, color_type, num_trans=0; -- png_bytep trans; -- png_color_16p trans_values; -+ png_uint_32 wdth, hght; -+ int bit_depth, color_type, num_trans=0; -+ png_bytep trans; -+ png_color_16p trans_values; - -- // Free chunk in case png_read_info uses longjmp. -- chunk.p.clear(); -- chunk.p.shrink_to_fit(); -+ // Free chunk in case png_read_info uses longjmp. -+ chunk.p.clear(); -+ chunk.p.shrink_to_fit(); - -- png_read_info( png_ptr, info_ptr ); -- png_get_IHDR(png_ptr, info_ptr, &wdth, &hght, -- &bit_depth, &color_type, 0, 0, 0); -+ png_read_info( m_png_ptr, m_info_ptr ); -+ png_get_IHDR(m_png_ptr, m_info_ptr, &wdth, &hght, -+ &bit_depth, &color_type, 0, 0, 0); - -- m_width = (int)wdth; -- m_height = (int)hght; -- m_color_type = color_type; -- m_bit_depth = bit_depth; -+ m_width = (int)wdth; -+ m_height = (int)hght; -+ m_color_type = color_type; -+ m_bit_depth = bit_depth; - -- if (bit_depth <= 8 || bit_depth == 16) -- { -- switch (color_type) -- { -- case PNG_COLOR_TYPE_RGB: -- case PNG_COLOR_TYPE_PALETTE: -- png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values); -- if (num_trans > 0) -- m_type = CV_8UC4; -- else -- m_type = CV_8UC3; -- break; -- case PNG_COLOR_TYPE_GRAY_ALPHA: -- 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)); -- result = true; -- } -- } -- } -+ if (m_is_fcTL_loaded && (int(x0 + w0) > m_width || int(y0 + h0) > m_height || dop > 2 || bop > 1)) -+ return false; - -- if(result) -+ if (bit_depth <= 8 || bit_depth == 16) - { -- m_png_ptrs = std::move(png_ptrs); -+ switch (color_type) -+ { -+ case PNG_COLOR_TYPE_RGB: -+ case PNG_COLOR_TYPE_PALETTE: -+ png_get_tRNS(m_png_ptr, m_info_ptr, &trans, &num_trans, &trans_values); -+ if (num_trans > 0) -+ m_type = CV_8UC4; -+ else -+ m_type = CV_8UC3; -+ break; -+ case PNG_COLOR_TYPE_GRAY_ALPHA: -+ 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)); - } - -- return result; -+ return true; - } - - bool PngDecoder::readData( Mat& img ) - { -+ // Declare dynamic variables before a potential longjmp. -+ AutoBuffer _buffer(m_height); -+ unsigned char** buffer = _buffer.data(); -+ Chunk chunk; -+ - if (m_frame_count > 1) - { - Mat mat_cur = Mat::zeros(img.rows, img.cols, m_type); -@@ -412,13 +430,14 @@ bool PngDecoder::readData( Mat& img ) - - frameCur.setMat(mat_cur); - -- processing_start((void*)&frameRaw, mat_cur); -- png_structp png_ptr = m_png_ptrs.getPng(); -- png_infop info_ptr = m_png_ptrs.getInfo(); -+ if (!processing_start((void*)&frameRaw, mat_cur)) -+ return false; -+ -+ if(setjmp(png_jmpbuf(m_png_ptr))) -+ return false; - - while (true) - { -- Chunk chunk; - id = read_chunk(chunk); - if (!id) - return false; -@@ -482,14 +501,14 @@ bool PngDecoder::readData( Mat& img ) - else if (id == id_IDAT) - { - m_is_IDAT_loaded = true; -- png_process_data(png_ptr, info_ptr, chunk.p.data(), chunk.p.size()); -+ png_process_data(m_png_ptr, m_info_ptr, chunk.p.data(), chunk.p.size()); - } - else if (id == id_fdAT && m_is_fcTL_loaded) - { - m_is_IDAT_loaded = true; - png_save_uint_32(&chunk.p[4], static_cast(chunk.p.size() - 16)); - memcpy(&chunk.p[8], "IDAT", 4); -- png_process_data(png_ptr, info_ptr, &chunk.p[4], chunk.p.size() - 4); -+ png_process_data(m_png_ptr, m_info_ptr, &chunk.p[4], chunk.p.size() - 4); - } - else if (id == id_IEND) - { -@@ -513,30 +532,24 @@ bool PngDecoder::readData( Mat& img ) - return true; - } - else -- png_process_data(png_ptr, info_ptr, chunk.p.data(), chunk.p.size()); -+ png_process_data(m_png_ptr, m_info_ptr, chunk.p.data(), chunk.p.size()); - } - return false; - } - - volatile bool result = false; -- AutoBuffer _buffer(m_height); -- unsigned char** buffer = _buffer.data(); - bool color = img.channels() > 1; - -- png_structp png_ptr = m_png_ptrs.getPng(); -- png_infop info_ptr = m_png_ptrs.getInfo(); -- png_infop end_info = m_png_ptrs.getEndInfo(); -- -- if( png_ptr && info_ptr && end_info && m_width && m_height ) -+ if( m_png_ptr && m_info_ptr && m_end_info && m_width && m_height ) - { -- if( setjmp( png_jmpbuf ( png_ptr ) ) == 0 ) -+ if( setjmp( png_jmpbuf ( m_png_ptr ) ) == 0 ) - { - int y; - - if( img.depth() == CV_8U && m_bit_depth == 16 ) -- png_set_strip_16( png_ptr ); -+ png_set_strip_16( m_png_ptr ); - else if( !isBigEndian() ) -- png_set_swap( png_ptr ); -+ png_set_swap( m_png_ptr ); - - if(img.channels() < 4) - { -@@ -548,46 +561,46 @@ bool PngDecoder::readData( Mat& img ) - * indicate that it is a good idea to always ask for - * stripping alpha.. 18.11.2004 Axel Walthelm - */ -- png_set_strip_alpha( png_ptr ); -+ png_set_strip_alpha( m_png_ptr ); - } else -- png_set_tRNS_to_alpha( png_ptr ); -+ png_set_tRNS_to_alpha( m_png_ptr ); - - if( m_color_type == PNG_COLOR_TYPE_PALETTE ) -- png_set_palette_to_rgb( png_ptr ); -+ png_set_palette_to_rgb( m_png_ptr ); - - if( (m_color_type & PNG_COLOR_MASK_COLOR) == 0 && m_bit_depth < 8 ) - #if (PNG_LIBPNG_VER_MAJOR*10000 + PNG_LIBPNG_VER_MINOR*100 + PNG_LIBPNG_VER_RELEASE >= 10209) || \ - (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR == 0 && PNG_LIBPNG_VER_RELEASE >= 18) -- png_set_expand_gray_1_2_4_to_8( png_ptr ); -+ png_set_expand_gray_1_2_4_to_8( m_png_ptr ); - #else - png_set_gray_1_2_4_to_8( png_ptr ); - #endif - - if( (m_color_type & PNG_COLOR_MASK_COLOR) && color && !m_use_rgb) -- png_set_bgr( png_ptr ); // convert RGB to BGR -+ png_set_bgr( m_png_ptr ); // convert RGB to BGR - else if( color ) -- png_set_gray_to_rgb( png_ptr ); // Gray->RGB -+ png_set_gray_to_rgb( m_png_ptr ); // Gray->RGB - else -- png_set_rgb_to_gray( png_ptr, 1, 0.299, 0.587 ); // RGB->Gray -+ png_set_rgb_to_gray( m_png_ptr, 1, 0.299, 0.587 ); // RGB->Gray - -- png_set_interlace_handling( png_ptr ); -- png_read_update_info( png_ptr, info_ptr ); -+ png_set_interlace_handling( m_png_ptr ); -+ png_read_update_info( m_png_ptr, m_info_ptr ); - - for( y = 0; y < m_height; y++ ) - buffer[y] = img.data + y*img.step; - -- png_read_image( png_ptr, buffer ); -- png_read_end( png_ptr, end_info ); -+ png_read_image( m_png_ptr, buffer ); -+ png_read_end( m_png_ptr, m_end_info ); - - #ifdef PNG_eXIf_SUPPORTED - png_uint_32 num_exif = 0; - png_bytep exif = 0; - - // Exif info could be in info_ptr (intro_info) or end_info per specification -- if( png_get_valid(png_ptr, info_ptr, PNG_INFO_eXIf) ) -- png_get_eXIf_1(png_ptr, info_ptr, &num_exif, &exif); -- else if( png_get_valid(png_ptr, end_info, PNG_INFO_eXIf) ) -- png_get_eXIf_1(png_ptr, end_info, &num_exif, &exif); -+ if( png_get_valid(m_png_ptr, m_info_ptr, PNG_INFO_eXIf) ) -+ png_get_eXIf_1(m_png_ptr, m_info_ptr, &num_exif, &exif); -+ else if( png_get_valid(m_png_ptr, m_end_info, PNG_INFO_eXIf) ) -+ png_get_eXIf_1(m_png_ptr, m_end_info, &num_exif, &exif); - - if( exif && num_exif > 0 ) - { -@@ -719,42 +732,34 @@ uint32_t PngDecoder::read_chunk(Chunk& chunk) - - bool PngDecoder::processing_start(void* frame_ptr, const Mat& img) - { -- static uint8_t header[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; -- -- PngPtrs png_ptrs; -- png_structp png_ptr = png_ptrs.getPng(); -- png_infop info_ptr = png_ptrs.getInfo(); -- -- if (!png_ptr || !info_ptr) { -+ if (!InitPngPtr()) - return false; -- } - -- if (setjmp(png_jmpbuf(png_ptr))) -- { -+ if (setjmp(png_jmpbuf(m_png_ptr))) - return false; -- } - -- m_png_ptrs = std::move(png_ptrs); -- png_set_crc_action(png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); -- png_set_progressive_read_fn(png_ptr, frame_ptr, (png_progressive_info_ptr)info_fn, row_fn, NULL); -+ static uint8_t header[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; -+ -+ png_set_crc_action(m_png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); -+ png_set_progressive_read_fn(m_png_ptr, frame_ptr, (png_progressive_info_ptr)info_fn, row_fn, NULL); - - if (img.channels() < 4) -- png_set_strip_alpha(png_ptr); -+ png_set_strip_alpha(m_png_ptr); - else -- png_set_tRNS_to_alpha(png_ptr); -+ png_set_tRNS_to_alpha(m_png_ptr); - -- png_process_data(png_ptr, info_ptr, header, 8); -- png_process_data(png_ptr, info_ptr, m_chunkIHDR.p.data(), m_chunkIHDR.p.size()); -+ png_process_data(m_png_ptr, m_info_ptr, header, 8); -+ png_process_data(m_png_ptr, m_info_ptr, m_chunkIHDR.p.data(), m_chunkIHDR.p.size()); - - if ((m_color_type & PNG_COLOR_MASK_COLOR) && img.channels() > 1 && !m_use_rgb) -- png_set_bgr(png_ptr); // convert RGB to BGR -+ png_set_bgr(m_png_ptr); // convert RGB to BGR - else if (img.channels() > 1) -- png_set_gray_to_rgb(png_ptr); // Gray->RGB -+ png_set_gray_to_rgb(m_png_ptr); // Gray->RGB - else -- png_set_rgb_to_gray(png_ptr, 1, 0.299, 0.587); // RGB->Gray -+ png_set_rgb_to_gray(m_png_ptr, 1, 0.299, 0.587); // RGB->Gray - - for (size_t i = 0; i < m_chunksInfo.size(); i++) -- png_process_data(png_ptr, info_ptr, m_chunksInfo[i].p.data(), m_chunksInfo[i].p.size()); -+ png_process_data(m_png_ptr, m_info_ptr, m_chunksInfo[i].p.data(), m_chunksInfo[i].p.size()); - - return true; - } -@@ -763,22 +768,17 @@ bool PngDecoder::processing_finish() - { - static uint8_t footer[12] = { 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130 }; - -- png_structp png_ptr = m_png_ptrs.getPng(); -- png_infop info_ptr = m_png_ptrs.getInfo(); -- -- if (!png_ptr) { -- m_png_ptrs.clear(); -+ if (!m_png_ptr) { - return false; - } - -- if (setjmp(png_jmpbuf(png_ptr))) -+ if (setjmp(png_jmpbuf(m_png_ptr))) - { -- m_png_ptrs.clear(); - return false; - } - -- png_process_data(png_ptr, info_ptr, footer, 12); -- m_png_ptrs.clear(); -+ png_process_data(m_png_ptr, m_info_ptr, footer, 12); -+ ClearPngPtr(); - - return true; - } -diff --git a/modules/imgcodecs/src/grfmt_png.hpp b/modules/imgcodecs/src/grfmt_png.hpp -index dec2cd0b61..5dfc86efcc 100644 ---- a/modules/imgcodecs/src/grfmt_png.hpp -+++ b/modules/imgcodecs/src/grfmt_png.hpp -@@ -130,56 +130,21 @@ public: - - ImageDecoder newDecoder() const CV_OVERRIDE; - --protected: -+private: - static void readDataFromBuf(void* png_ptr, uchar* dst, size_t size); - static void info_fn(png_structp png_ptr, png_infop info_ptr); - static void row_fn(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass); -- bool processing_start(void* frame_ptr, const Mat& img); -- bool processing_finish(); -+ CV_NODISCARD_STD bool processing_start(void* frame_ptr, const Mat& img); -+ CV_NODISCARD_STD bool processing_finish(); - void compose_frame(std::vector& rows_dst, const std::vector& rows_src, unsigned char bop, uint32_t x, uint32_t y, uint32_t w, uint32_t h, Mat& img); -- bool read_from_io(void* buffer, size_t num_bytes); -+ CV_NODISCARD_STD bool read_from_io(void* buffer, size_t num_bytes); - uint32_t read_chunk(Chunk& chunk); -+ CV_NODISCARD_STD bool InitPngPtr(); -+ void ClearPngPtr(); - -- struct PngPtrs { -- public: -- PngPtrs() { -- png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 ); -- if (png_ptr) { -- info_ptr = png_create_info_struct( png_ptr ); -- end_info = png_create_info_struct( png_ptr ); -- } else { -- info_ptr = end_info = nullptr; -- } -- } -- ~PngPtrs() { -- clear(); -- } -- PngPtrs& operator=(PngPtrs&& other) { -- clear(); -- png_ptr = other.png_ptr; -- info_ptr = other.info_ptr; -- end_info = other.end_info; -- other.png_ptr = nullptr; -- other.info_ptr = other.end_info = nullptr; -- return *this; -- } -- void clear() { -- if (png_ptr) { -- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); -- png_ptr = nullptr; -- info_ptr = end_info = nullptr; -- } -- } -- png_structp getPng() const { return png_ptr; } -- png_infop getInfo() const { return info_ptr; } -- png_infop getEndInfo() const { return end_info; } -- private: -- png_structp png_ptr; // pointer to decompression structure -- png_infop info_ptr; // pointer to image information structure -- png_infop end_info; // pointer to one more image information structure -- }; -- -- PngPtrs m_png_ptrs; -+ png_structp m_png_ptr = nullptr; // pointer to decompression structure -+ png_infop m_info_ptr = nullptr; // pointer to image information structure -+ png_infop m_end_info = nullptr; // pointer to one more image information structure - int m_bit_depth; - FILE* m_f; - int m_color_type; --- -2.48.1 - diff --git a/0004-Move-the-checks-to-read_chunk.patch b/0004-Move-the-checks-to-read_chunk.patch deleted file mode 100644 index 5137872..0000000 --- a/0004-Move-the-checks-to-read_chunk.patch +++ /dev/null @@ -1,121 +0,0 @@ -From eba1a8955f9d7f8aa8c6b3ddee4565ee4185136c Mon Sep 17 00:00:00 2001 -From: Vincent Rabaud -Date: Thu, 23 Jan 2025 16:30:38 +0100 -Subject: [PATCH 04/10] Move the checks to read_chunk. - -Only user chunks need to be compared to PNG_USER_CHUNK_MALLOC_MAX ---- - modules/imgcodecs/src/grfmt_png.cpp | 60 +++++++++++++++++------------ - 1 file changed, 36 insertions(+), 24 deletions(-) - -diff --git a/modules/imgcodecs/src/grfmt_png.cpp b/modules/imgcodecs/src/grfmt_png.cpp -index 105288c5e5..64ef56c8c5 100644 ---- a/modules/imgcodecs/src/grfmt_png.cpp -+++ b/modules/imgcodecs/src/grfmt_png.cpp -@@ -278,12 +278,8 @@ bool PngDecoder::readHeader() - return false; - - id = read_chunk(m_chunkIHDR); -- // 8=HDR+size, 13=size of IHDR chunk, 4=CRC -- // http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.IHDR -- if (!(id == id_IHDR && m_chunkIHDR.p.size() == 8 + 13 + 4)) -- { -+ if (id != id_IHDR) - return false; -- } - - m_is_fcTL_loaded = false; - while (true) -@@ -306,10 +302,7 @@ bool PngDecoder::readHeader() - - if (id == id_acTL) - { -- // 8=HDR+size, 8=size of acTL chunk, 4=CRC - // https://wiki.mozilla.org/APNG_Specification#%60acTL%60:_The_Animation_Control_Chunk -- if (chunk.p.size() != 8 + 8 + 4) -- return false; - m_animation.loop_count = png_get_uint_32(&chunk.p[12]); - - m_frame_count = png_get_uint_32(&chunk.p[8]); -@@ -319,10 +312,7 @@ bool PngDecoder::readHeader() - - if (id == id_fcTL) - { -- // 8=HDR+size, 26=size of fcTL chunk, 4=CRC - // https://wiki.mozilla.org/APNG_Specification#%60fcTL%60:_The_Frame_Control_Chunk -- if (chunk.p.size() != 8 + 26 + 4) -- return false; - m_is_fcTL_loaded = true; - w0 = png_get_uint_32(&chunk.p[12]); - h0 = png_get_uint_32(&chunk.p[16]); -@@ -336,11 +326,7 @@ bool PngDecoder::readHeader() - - if (id == id_bKGD) - { -- // 8=HDR+size, ??=size of bKGD chunk, 4=CRC - // The spec is actually more complex: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.bKGD -- // TODO: we only check that 4 bytes can be read from &chunk.p[8]. Fix. -- if (chunk.p.size() < 8 + 4) -- return false; - int bgcolor = png_get_uint_32(&chunk.p[8]); - m_animation.bgcolor[3] = (bgcolor >> 24) & 0xFF; - m_animation.bgcolor[2] = (bgcolor >> 16) & 0xFF; -@@ -713,20 +699,46 @@ bool PngDecoder::read_from_io(void* buffer, size_t num_bytes) - - uint32_t PngDecoder::read_chunk(Chunk& chunk) - { -- unsigned char len[4]; -- if (read_from_io(&len, 4)) -- { -- const size_t size = static_cast(png_get_uint_32(len)) + 12; -+ unsigned char size_id[8]; -+ if (!read_from_io(&size_id, 8)) -+ return 0; -+ const size_t size = static_cast(png_get_uint_32(size_id)) + 12; -+ -+ const uint32_t id = *(uint32_t*)(&size_id[4]); -+ if (id == id_IHDR) { -+ // 8=HDR+size, 13=size of IHDR chunk, 4=CRC -+ // http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.IHDR -+ if (size != 8 + 13 + 4) -+ return 0; -+ } else if (id == id_acTL) { -+ // 8=HDR+size, 8=size of acTL chunk, 4=CRC -+ // https://wiki.mozilla.org/APNG_Specification#%60acTL%60:_The_Animation_Control_Chunk -+ if (size != 8 + 8 + 4) -+ return 0; -+ } else if (id == id_fcTL) { -+ // 8=HDR+size, 26=size of fcTL chunk, 4=CRC -+ // https://wiki.mozilla.org/APNG_Specification#%60fcTL%60:_The_Frame_Control_Chunk -+ if (size != 8 + 26 + 4) -+ return 0; -+ } else if (id == id_bKGD) { -+ // 8=HDR+size, ??=size of bKGD chunk, 4=CRC -+ // The spec is actually more complex: -+ // http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.bKGD -+ // TODO: we only check that 4 bytes can be read from &chunk.p[8]. Fix. -+ if (size < 8 + 4) -+ return 0; -+ } else if (id != id_fdAT && id != id_IDAT && id != id_IEND && id != id_PLTE && id != id_tRNS) { - if (size > PNG_USER_CHUNK_MALLOC_MAX) - { -- CV_LOG_WARNING(NULL, "chunk data is too large"); -+ CV_LOG_WARNING(NULL, "user chunk data is too large"); - return 0; - } -- chunk.p.resize(size); -- memcpy(chunk.p.data(), len, 4); -- if (read_from_io(&chunk.p[4], chunk.p.size() - 4)) -- return *(uint32_t*)(&chunk.p[4]); - } -+ -+ chunk.p.resize(size); -+ memcpy(chunk.p.data(), size_id, 8); -+ if (read_from_io(&chunk.p[8], chunk.p.size() - 8)) -+ return id; - return 0; - } - --- -2.48.1 - diff --git a/0005-minor-improvement-for-better-code-readibility.patch b/0005-minor-improvement-for-better-code-readibility.patch deleted file mode 100644 index c677c33..0000000 --- a/0005-minor-improvement-for-better-code-readibility.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 49c3a5eca58276daca4207c38a1579080aade23e Mon Sep 17 00:00:00 2001 -From: Suleyman TURKMEN -Date: Fri, 24 Jan 2025 15:31:53 +0300 -Subject: [PATCH 05/10] minor improvement for better code readibility - ---- - modules/imgcodecs/src/grfmt_png.cpp | 41 ++++++++++++++++++----------- - modules/imgcodecs/src/grfmt_png.hpp | 27 +++++++++++++++++-- - 2 files changed, 50 insertions(+), 18 deletions(-) - -diff --git a/modules/imgcodecs/src/grfmt_png.cpp b/modules/imgcodecs/src/grfmt_png.cpp -index 64ef56c8c5..08e37ec0c3 100644 ---- a/modules/imgcodecs/src/grfmt_png.cpp -+++ b/modules/imgcodecs/src/grfmt_png.cpp -@@ -274,7 +274,7 @@ bool PngDecoder::readHeader() - } - - // Read PNG header: 137 80 78 71 13 10 26 10 -- if (!read_from_io(&sig, 8)) -+ if (!readFromStreamOrBuffer(&sig, 8)) - return false; - - id = read_chunk(m_chunkIHDR); -@@ -682,7 +682,7 @@ void PngDecoder::compose_frame(std::vector& rows_dst, const std::vect - }); - } - --bool PngDecoder::read_from_io(void* buffer, size_t num_bytes) -+bool PngDecoder::readFromStreamOrBuffer(void* buffer, size_t num_bytes) - { - if (m_f) - return fread(buffer, 1, num_bytes, m_f) == num_bytes; -@@ -700,7 +700,7 @@ bool PngDecoder::read_from_io(void* buffer, size_t num_bytes) - uint32_t PngDecoder::read_chunk(Chunk& chunk) - { - unsigned char size_id[8]; -- if (!read_from_io(&size_id, 8)) -+ if (!readFromStreamOrBuffer(&size_id, 8)) - return 0; - const size_t size = static_cast(png_get_uint_32(size_id)) + 12; - -@@ -737,7 +737,7 @@ uint32_t PngDecoder::read_chunk(Chunk& chunk) - - chunk.p.resize(size); - memcpy(chunk.p.data(), size_id, 8); -- if (read_from_io(&chunk.p[8], chunk.p.size() - 8)) -+ if (readFromStreamOrBuffer(&chunk.p[8], chunk.p.size() - 8)) - return id; - return 0; - } -@@ -960,15 +960,24 @@ bool PngEncoder::write( const Mat& img, const std::vector& params ) - return result; - } - --size_t PngEncoder::write_to_io(void const* _Buffer, size_t _ElementSize, size_t _ElementCount, FILE * _Stream) -+size_t PngEncoder::writeToStreamOrBuffer(void const* buffer, size_t num_bytes, FILE* stream) - { -- if (_Stream) -- return fwrite(_Buffer, _ElementSize, _ElementCount, _Stream); -+ if (!buffer || !num_bytes) -+ return 0; // Handle null buffer or empty writes -+ -+ if (stream) -+ { -+ size_t written = fwrite(buffer, 1, num_bytes, stream); -+ return written; // fwrite handles the write count -+ } - - size_t cursz = m_buf->size(); -- m_buf->resize(cursz + _ElementCount); -- memcpy( &(*m_buf)[cursz], _Buffer, _ElementCount ); -- return _ElementCount; -+ if (cursz + num_bytes > m_buf->max_size()) -+ throw std::runtime_error("Buffer size exceeds maximum capacity"); -+ -+ m_buf->resize(cursz + num_bytes); -+ memcpy(&(*m_buf)[cursz], buffer, num_bytes); -+ return num_bytes; - } - - void PngEncoder::writeChunk(FILE* f, const char* name, unsigned char* data, uint32_t length) -@@ -977,26 +986,26 @@ void PngEncoder::writeChunk(FILE* f, const char* name, unsigned char* data, uint - uint32_t crc = crc32(0, Z_NULL, 0); - - png_save_uint_32(buf, length); -- write_to_io(buf, 1, 4, f); -- write_to_io(name, 1, 4, f); -+ writeToStreamOrBuffer(buf, 4, f); -+ writeToStreamOrBuffer(name, 4, f); - crc = crc32(crc, (const Bytef*)name, 4); - - if (memcmp(name, "fdAT", 4) == 0) - { - png_save_uint_32(buf, next_seq_num++); -- write_to_io(buf, 1, 4, f); -+ writeToStreamOrBuffer(buf, 4, f); - crc = crc32(crc, buf, 4); - length -= 4; - } - - if (data != NULL && length > 0) - { -- write_to_io(data, 1, length, f); -+ writeToStreamOrBuffer(data, length, f); - crc = crc32(crc, data, length); - } - - png_save_uint_32(buf, crc); -- write_to_io(buf, 1, 4, f); -+ writeToStreamOrBuffer(buf, 4, f); - } - - void PngEncoder::writeIDATs(FILE* f, int frame, unsigned char* data, uint32_t length, uint32_t idat_size) -@@ -1521,7 +1530,7 @@ bool PngEncoder::writeanimation(const Animation& animation, const std::vector& rows_dst, const std::vector& rows_src, unsigned char bop, uint32_t x, uint32_t y, uint32_t w, uint32_t h, Mat& img); -- CV_NODISCARD_STD bool read_from_io(void* buffer, size_t num_bytes); -+ /** -+ * @brief Reads data from an I/O source into the provided buffer. -+ * @param buffer Pointer to the buffer where the data will be stored. -+ * @param num_bytes Number of bytes to read into the buffer. -+ * @return true if the operation is successful, false otherwise. -+ */ -+ CV_NODISCARD_STD bool readFromStreamOrBuffer(void* buffer, size_t num_bytes); - uint32_t read_chunk(Chunk& chunk); - CV_NODISCARD_STD bool InitPngPtr(); - void ClearPngPtr(); -@@ -185,7 +191,24 @@ public: - protected: - static void writeDataToBuf(void* png_ptr, unsigned char* src, size_t size); - static void flushBuf(void* png_ptr); -- size_t write_to_io(void const* _Buffer, size_t _ElementSize, size_t _ElementCount, FILE* _Stream); -+ /** -+ * @brief Writes data to an output destination, either a file stream or an in-memory buffer. -+ * -+ * This function handles two output scenarios: -+ * 1. If a file stream is provided, the data is written to the stream using `fwrite`. -+ * 2. If `stream` is null, the data is written to an in-memory buffer (`m_buf`), which is resized as needed. -+ * -+ * @param buffer Pointer to the data to be written. -+ * @param num_bytes The number of bytes to be written. -+ * @param stream Pointer to the file stream for writing. If null, the data is written to the in-memory buffer. -+ * @return The number of bytes successfully written. -+ * - For file-based writes, this is the number of bytes written to the stream. -+ * - For buffer-based writes, this is the total number of bytes added to the buffer. -+ * -+ * @throws std::runtime_error If the in-memory buffer (`m_buf`) exceeds its maximum capacity. -+ * @note If `num_bytes` is 0 or `buffer` is null, the function returns 0. -+ */ -+ size_t writeToStreamOrBuffer(void const* buffer, size_t num_bytes, FILE* stream); - - private: - void writeChunk(FILE* f, const char* name, unsigned char* data, uint32_t length); --- -2.48.1 - diff --git a/0006-Merge-pull-request-26835-from-sturkmen72-patch-4.patch b/0006-Merge-pull-request-26835-from-sturkmen72-patch-4.patch deleted file mode 100644 index ba5c46f..0000000 --- a/0006-Merge-pull-request-26835-from-sturkmen72-patch-4.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 8131e27e824740afa447a129e72a2f6a3876cbc9 Mon Sep 17 00:00:00 2001 -From: Suleyman TURKMEN -Date: Sat, 25 Jan 2025 09:31:00 +0300 -Subject: [PATCH 06/10] Merge pull request #26835 from sturkmen72:patch-4 - -Corrections on bKGD chunk writing and reading in PNG #26835 - -### 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 -- [ ] 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. -- [ ] The feature is well documented and sample code can be built with the project CMake ---- - modules/imgcodecs/src/grfmt_png.cpp | 26 ++++++++--------- - modules/imgcodecs/test/test_animation.cpp | 35 ++++++++++++++++++++++- - 2 files changed, 46 insertions(+), 15 deletions(-) - -diff --git a/modules/imgcodecs/src/grfmt_png.cpp b/modules/imgcodecs/src/grfmt_png.cpp -index 08e37ec0c3..4ec3280607 100644 ---- a/modules/imgcodecs/src/grfmt_png.cpp -+++ b/modules/imgcodecs/src/grfmt_png.cpp -@@ -327,11 +327,10 @@ bool PngDecoder::readHeader() - if (id == id_bKGD) - { - // The spec is actually more complex: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.bKGD -- int bgcolor = png_get_uint_32(&chunk.p[8]); -- m_animation.bgcolor[3] = (bgcolor >> 24) & 0xFF; -- m_animation.bgcolor[2] = (bgcolor >> 16) & 0xFF; -- m_animation.bgcolor[1] = (bgcolor >> 8) & 0xFF; -- m_animation.bgcolor[0] = bgcolor & 0xFF; -+ m_animation.bgcolor[0] = png_get_uint_16(&chunk.p[8]); -+ m_animation.bgcolor[1] = png_get_uint_16(&chunk.p[10]); -+ m_animation.bgcolor[2] = png_get_uint_16(&chunk.p[12]); -+ m_animation.bgcolor[3] = 0; - } - - if (id == id_PLTE || id == id_tRNS) -@@ -721,11 +720,10 @@ uint32_t PngDecoder::read_chunk(Chunk& chunk) - if (size != 8 + 26 + 4) - return 0; - } else if (id == id_bKGD) { -- // 8=HDR+size, ??=size of bKGD chunk, 4=CRC -+ // 8=HDR+size, (1, 2 or 6)=size of bKGD chunk, 4=CRC - // The spec is actually more complex: - // http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.bKGD -- // TODO: we only check that 4 bytes can be read from &chunk.p[8]. Fix. -- if (size < 8 + 4) -+ if (size != 8 + 1 + 4 && size != 8 + 2 + 4 && size != 8 + 6 + 4) - return 0; - } else if (id != id_fdAT && id != id_IDAT && id != id_IEND && id != id_PLTE && id != id_tRNS) { - if (size > PNG_USER_CHUNK_MALLOC_MAX) -@@ -1542,13 +1540,13 @@ bool PngEncoder::writeanimation(const Animation& animation, const std::vector 0) - writeChunk(m_f, "PLTE", (unsigned char*)(&palette), palsize * 3); - -- if ((animation.bgcolor != Scalar()) && (animation.frames.size() > 1)) -+ if ((animation.bgcolor != Scalar()) && coltype) - { -- uint64_t bgvalue = (static_cast(animation.bgcolor[0]) & 0xFF) << 24 | -- (static_cast(animation.bgcolor[1]) & 0xFF) << 16 | -- (static_cast(animation.bgcolor[2]) & 0xFF) << 8 | -- (static_cast(animation.bgcolor[3]) & 0xFF); -- writeChunk(m_f, "bKGD", (unsigned char*)(&bgvalue), 6); //the bKGD chunk must precede the first IDAT chunk, and must follow the PLTE chunk. -+ unsigned char bgvalue[6] = {}; -+ bgvalue[1] = animation.bgcolor[0]; -+ bgvalue[3] = animation.bgcolor[1]; -+ bgvalue[5] = animation.bgcolor[2]; -+ writeChunk(m_f, "bKGD", bgvalue, 6); //the bKGD chunk must precede the first IDAT chunk, and must follow the PLTE chunk. - } - - if (trnssize > 0) -diff --git a/modules/imgcodecs/test/test_animation.cpp b/modules/imgcodecs/test/test_animation.cpp -index e8c42cbcc0..df0a00a8b1 100644 ---- a/modules/imgcodecs/test/test_animation.cpp -+++ b/modules/imgcodecs/test/test_animation.cpp -@@ -425,6 +425,39 @@ TEST(Imgcodecs_APNG, imwriteanimation_rgb) - EXPECT_EQ(0, remove(output.c_str())); - } - -+TEST(Imgcodecs_APNG, imwriteanimation_gray) -+{ -+ Animation s_animation, l_animation; -+ EXPECT_TRUE(fillFrames(s_animation, false)); -+ -+ for (size_t i = 0; i < s_animation.frames.size(); i++) -+ { -+ cvtColor(s_animation.frames[i], s_animation.frames[i], COLOR_BGR2GRAY); -+ } -+ -+ s_animation.bgcolor = Scalar(50, 100, 150); -+ string output = cv::tempfile(".png"); -+ // Write the animation to a .png file and verify success. -+ EXPECT_TRUE(imwriteanimation(output, s_animation)); -+ -+ // Read the animation back and compare with the original. -+ EXPECT_TRUE(imreadanimation(output, l_animation)); -+ -+ EXPECT_EQ(Scalar(), l_animation.bgcolor); -+ size_t expected_frame_count = s_animation.frames.size() - 2; -+ -+ // Verify that the number of frames matches the expected count. -+ EXPECT_EQ(expected_frame_count, imcount(output)); -+ EXPECT_EQ(expected_frame_count, l_animation.frames.size()); -+ -+ EXPECT_EQ(0, remove(output.c_str())); -+ -+ for (size_t i = 0; i < l_animation.frames.size(); i++) -+ { -+ EXPECT_EQ(0, cvtest::norm(s_animation.frames[i], l_animation.frames[i], NORM_INF)); -+ } -+} -+ - TEST(Imgcodecs_APNG, imwritemulti_rgba) - { - Animation s_animation; -@@ -492,7 +525,7 @@ TEST(Imgcodecs_APNG, imwriteanimation_bgcolor) - { - Animation s_animation, l_animation; - EXPECT_TRUE(fillFrames(s_animation, true, 2)); -- s_animation.bgcolor = Scalar(50, 100, 150, 128); // different values for test purpose. -+ s_animation.bgcolor = Scalar(50, 100, 150); // will be written in bKGD chunk as RGB. - - // Create a temporary output filename for saving the animation. - string output = cv::tempfile(".png"); --- -2.48.1 - diff --git a/0007-fix-for-large-tEXt-chunk.patch b/0007-fix-for-large-tEXt-chunk.patch deleted file mode 100644 index 20193cb..0000000 --- a/0007-fix-for-large-tEXt-chunk.patch +++ /dev/null @@ -1,39 +0,0 @@ -From d6c4ac2e5e9cb7ea607ecb8e70884a3c5a06654c Mon Sep 17 00:00:00 2001 -From: Suleyman TURKMEN -Date: Tue, 28 Jan 2025 01:06:41 +0300 -Subject: [PATCH 07/10] fix for large tEXt chunk - ---- - modules/imgcodecs/src/grfmt_png.cpp | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/modules/imgcodecs/src/grfmt_png.cpp b/modules/imgcodecs/src/grfmt_png.cpp -index 4ec3280607..909a9017b2 100644 ---- a/modules/imgcodecs/src/grfmt_png.cpp -+++ b/modules/imgcodecs/src/grfmt_png.cpp -@@ -126,9 +126,10 @@ const uint32_t id_acTL = 0x4C546361; // Animation control chunk - const uint32_t id_fcTL = 0x4C546366; // Frame control chunk - const uint32_t id_IDAT = 0x54414449; // first frame and/or default image - const uint32_t id_fdAT = 0x54416466; // Frame data chunk --const uint32_t id_PLTE = 0x45544C50; --const uint32_t id_bKGD = 0x44474B62; --const uint32_t id_tRNS = 0x534E5274; -+const uint32_t id_PLTE = 0x45544C50; // The PLTE chunk contains a color palette for indexed-color images -+const uint32_t id_bKGD = 0x44474B62; // The bKGD chunk specifies a default background color for the image -+const uint32_t id_tRNS = 0x534E5274; // The tRNS chunk provides transparency information -+const uint32_t id_tEXt = 0x74584574; // The tEXt chunk stores metadata as text in key-value pairs - const uint32_t id_IEND = 0x444E4549; // end/footer chunk - - APNGFrame::APNGFrame() -@@ -725,7 +726,7 @@ uint32_t PngDecoder::read_chunk(Chunk& chunk) - // http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.bKGD - if (size != 8 + 1 + 4 && size != 8 + 2 + 4 && size != 8 + 6 + 4) - return 0; -- } else if (id != id_fdAT && id != id_IDAT && id != id_IEND && id != id_PLTE && id != id_tRNS) { -+ } else if (id != id_fdAT && id != id_IDAT && id != id_IEND && id != id_PLTE && id != id_tEXt && id != id_tRNS) { - if (size > PNG_USER_CHUNK_MALLOC_MAX) - { - CV_LOG_WARNING(NULL, "user chunk data is too large"); --- -2.48.1 - diff --git a/0008-Merge-pull-request-26854-from-vrabaud-png_leak.patch b/0008-Merge-pull-request-26854-from-vrabaud-png_leak.patch deleted file mode 100644 index f673d2f..0000000 --- a/0008-Merge-pull-request-26854-from-vrabaud-png_leak.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0d99c4283620671be3009ec00eb260e5a759cc39 Mon Sep 17 00:00:00 2001 -From: Vincent Rabaud -Date: Fri, 31 Jan 2025 09:00:23 +0100 -Subject: [PATCH 08/10] Merge pull request #26854 from vrabaud:png_leak - -Fix oss-fuzz bugs 391934081 and 392318892 #26854 - -- fix a potential overflow in x0+w0 -- use the proper function to deal with background color to deal with all cases of the spec -- use BGR layout for APNG background color - -### 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. -- [ ] The feature is well documented and sample code can be built with the project CMake ---- - .../imgcodecs/include/opencv2/imgcodecs.hpp | 2 +- - modules/imgcodecs/src/grfmt_png.cpp | 19 +++++++------------ - 2 files changed, 8 insertions(+), 13 deletions(-) - -diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp -index cd648c2c6e..c802033e6b 100644 ---- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp -+++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp -@@ -263,7 +263,7 @@ struct CV_EXPORTS_W_SIMPLE Animation - - If a negative value or a value beyond the maximum of `0xffff` (65535) is provided, it is reset to `0` - (infinite looping) to maintain valid bounds. - -- @param bgColor A `Scalar` object representing the background color in BGRA format: -+ @param bgColor A `Scalar` object representing the background color in BGR format: - - Defaults to `Scalar()`, indicating an empty color (usually transparent if supported). - - This background color provides a solid fill behind frames that have transparency, ensuring a consistent display appearance. - */ -diff --git a/modules/imgcodecs/src/grfmt_png.cpp b/modules/imgcodecs/src/grfmt_png.cpp -index 909a9017b2..f7a19c2bf5 100644 ---- a/modules/imgcodecs/src/grfmt_png.cpp -+++ b/modules/imgcodecs/src/grfmt_png.cpp -@@ -325,15 +325,6 @@ bool PngDecoder::readHeader() - bop = chunk.p[33]; - } - -- if (id == id_bKGD) -- { -- // The spec is actually more complex: http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.bKGD -- m_animation.bgcolor[0] = png_get_uint_16(&chunk.p[8]); -- m_animation.bgcolor[1] = png_get_uint_16(&chunk.p[10]); -- m_animation.bgcolor[2] = png_get_uint_16(&chunk.p[12]); -- m_animation.bgcolor[3] = 0; -- } -- - if (id == id_PLTE || id == id_tRNS) - m_chunksInfo.push_back(chunk); - } -@@ -356,9 +347,13 @@ bool PngDecoder::readHeader() - m_color_type = color_type; - m_bit_depth = bit_depth; - -- if (m_is_fcTL_loaded && (int(x0 + w0) > m_width || int(y0 + h0) > m_height || dop > 2 || bop > 1)) -+ if (m_is_fcTL_loaded && ((long long int)x0 + w0 > m_width || (long long int)y0 + h0 > m_height || dop > 2 || bop > 1)) - return false; - -+ png_color_16p background_color; -+ if (png_get_bKGD(m_png_ptr, m_info_ptr, &background_color)) -+ m_animation.bgcolor = Scalar(background_color->blue, background_color->green, background_color->red); -+ - if (bit_depth <= 8 || bit_depth == 16) - { - switch (color_type) -@@ -1544,9 +1539,9 @@ bool PngEncoder::writeanimation(const Animation& animation, const std::vector -Date: Tue, 4 Feb 2025 12:21:55 +0300 -Subject: [PATCH 09/10] Merge pull request #26872 from - sturkmen72:ImageEncoders_revisions - -Performance tests for image encoders and decoders and code cleanup #26872 - -### 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 -- [ ] 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. -- [ ] The feature is well documented and sample code can be built with the project CMake ---- - modules/highgui/src/window_w32.cpp | 10 +- - modules/imgcodecs/perf/perf_decode_encode.cpp | 131 ++++++++++++++++++ - modules/imgcodecs/src/grfmt_avif.cpp | 5 - - modules/imgcodecs/src/grfmt_avif.hpp | 1 - - modules/imgcodecs/src/grfmt_base.cpp | 8 +- - modules/imgcodecs/src/grfmt_base.hpp | 5 +- - modules/imgcodecs/src/grfmt_gif.cpp | 10 +- - modules/imgcodecs/src/grfmt_gif.hpp | 3 - - modules/imgcodecs/src/grfmt_png.cpp | 6 +- - modules/imgcodecs/src/loadsave.cpp | 2 +- - 10 files changed, 155 insertions(+), 26 deletions(-) - create mode 100644 modules/imgcodecs/perf/perf_decode_encode.cpp - -diff --git a/modules/highgui/src/window_w32.cpp b/modules/highgui/src/window_w32.cpp -index 2543c81c6a..8e041c9609 100644 ---- a/modules/highgui/src/window_w32.cpp -+++ b/modules/highgui/src/window_w32.cpp -@@ -2170,9 +2170,15 @@ static void showSaveDialog(CvWindow& window) - #ifdef HAVE_WEBP - "WebP files (*.webp)\0*.webp\0" - #endif -- "Portable image format (*.pbm;*.pgm;*.ppm;*.pxm;*.pnm)\0*.pbm;*.pgm;*.ppm;*.pxm;*.pnm\0" -+ "Portable image format (*.pbm;*.pgm;*.ppm;*.pnm;*.pam)\0*.pbm;*.pgm;*.ppm;*.pnm;*.pam\0" - #ifdef HAVE_OPENEXR - "OpenEXR Image files (*.exr)\0*.exr\0" -+#endif -+#ifdef HAVE_AVIF -+ "AVIF files (*.avif)\0*.avif\0" -+#endif -+#ifdef HAVE_IMGCODEC_GIF -+ "Graphics Interchange Format 89a(*.gif)\0*.gif\0" - #endif - "Radiance HDR (*.hdr;*.pic)\0*.hdr;*.pic\0" - "Sun raster files (*.sr;*.ras)\0*.sr;*.ras\0" -@@ -2194,7 +2200,7 @@ static void showSaveDialog(CvWindow& window) - } - #else - CV_UNUSED(window); -- CV_LOG_WARNING("Save dialog requires enabled 'imgcodecs' module."); -+ CV_LOG_WARNING(NULL, "Save dialog requires enabled 'imgcodecs' module."); - return; - #endif - } -diff --git a/modules/imgcodecs/perf/perf_decode_encode.cpp b/modules/imgcodecs/perf/perf_decode_encode.cpp -new file mode 100644 -index 0000000000..ce693cb878 ---- /dev/null -+++ b/modules/imgcodecs/perf/perf_decode_encode.cpp -@@ -0,0 +1,131 @@ -+// 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 "perf_precomp.hpp" -+ -+namespace opencv_test -+{ -+ -+#ifdef HAVE_PNG -+ -+using namespace perf; -+ -+typedef perf::TestBaseWithParam Decode; -+typedef perf::TestBaseWithParam Encode; -+ -+const string exts[] = { -+#ifdef HAVE_AVIF -+ ".avif", -+#endif -+ ".bmp", -+#ifdef HAVE_IMGCODEC_GIF -+ ".gif", -+#endif -+#if (defined(HAVE_JASPER) && defined(OPENCV_IMGCODECS_ENABLE_JASPER_TESTS)) \ -+ || defined(HAVE_OPENJPEG) -+ ".jp2", -+#endif -+#ifdef HAVE_JPEG -+ ".jpg", -+#endif -+#ifdef HAVE_JPEGXL -+ ".jxl", -+#endif -+ ".png", -+#ifdef HAVE_IMGCODEC_PXM -+ ".ppm", -+#endif -+#ifdef HAVE_IMGCODEC_SUNRASTER -+ ".ras", -+#endif -+#ifdef HAVE_TIFF -+ ".tiff", -+#endif -+#ifdef HAVE_WEBP -+ ".webp", -+#endif -+}; -+ -+const string exts_multi[] = { -+#ifdef HAVE_AVIF -+ ".avif", -+#endif -+#ifdef HAVE_IMGCODEC_GIF -+ ".gif", -+#endif -+ ".png", -+#ifdef HAVE_TIFF -+ ".tiff", -+#endif -+#ifdef HAVE_WEBP -+ ".webp", -+#endif -+}; -+ -+PERF_TEST_P(Decode, bgr, testing::ValuesIn(exts)) -+{ -+ String filename = getDataPath("perf/1920x1080.png"); -+ -+ Mat src = imread(filename); -+ EXPECT_FALSE(src.empty()) << "Cannot open test image perf/1920x1080.png"; -+ vector buf; -+ EXPECT_TRUE(imencode(GetParam(), src, buf)); -+ -+ TEST_CYCLE() imdecode(buf, IMREAD_UNCHANGED); -+ -+ SANITY_CHECK_NOTHING(); -+} -+ -+PERF_TEST_P(Decode, rgb, testing::ValuesIn(exts)) -+{ -+ String filename = getDataPath("perf/1920x1080.png"); -+ -+ Mat src = imread(filename); -+ EXPECT_FALSE(src.empty()) << "Cannot open test image perf/1920x1080.png"; -+ vector buf; -+ EXPECT_TRUE(imencode(GetParam(), src, buf)); -+ -+ TEST_CYCLE() imdecode(buf, IMREAD_COLOR_RGB); -+ -+ SANITY_CHECK_NOTHING(); -+} -+ -+PERF_TEST_P(Encode, bgr, testing::ValuesIn(exts)) -+{ -+ String filename = getDataPath("perf/1920x1080.png"); -+ -+ Mat src = imread(filename); -+ EXPECT_FALSE(src.empty()) << "Cannot open test image perf/1920x1080.png"; -+ vector buf; -+ -+ TEST_CYCLE() imencode(GetParam(), src, buf); -+ -+ std::cout << "Encoded buffer size: " << buf.size() -+ << " bytes, Compression ratio: " << std::fixed << std::setprecision(2) -+ << (static_cast(buf.size()) / (src.total() * src.channels())) * 100.0 << "%" << std::endl; -+ -+ SANITY_CHECK_NOTHING(); -+} -+ -+PERF_TEST_P(Encode, multi, testing::ValuesIn(exts_multi)) -+{ -+ String filename = getDataPath("perf/1920x1080.png"); -+ vector vec; -+ EXPECT_TRUE(imreadmulti(filename, vec)); -+ vec.push_back(vec.back().clone()); -+ circle(vec.back(), Point(100, 100), 45, Scalar(0, 0, 255, 0), 2, LINE_AA); -+ vector buf; -+ EXPECT_TRUE(imwrite("test" + GetParam(), vec)); -+ -+ TEST_CYCLE() imencode(GetParam(), vec, buf); -+ -+ std::cout << "Encoded buffer size: " << buf.size() -+ << " bytes, Compression ratio: " << std::fixed << std::setprecision(2) -+ << (static_cast(buf.size()) / (vec[0].total() * vec[0].channels())) * 100.0 << "%" << std::endl; -+ -+ SANITY_CHECK_NOTHING(); -+} -+#endif // HAVE_PNG -+ -+} // namespace -diff --git a/modules/imgcodecs/src/grfmt_avif.cpp b/modules/imgcodecs/src/grfmt_avif.cpp -index d3fb500604..c35eb50306 100644 ---- a/modules/imgcodecs/src/grfmt_avif.cpp -+++ b/modules/imgcodecs/src/grfmt_avif.cpp -@@ -298,11 +298,6 @@ bool AvifEncoder::isFormatSupported(int depth) const { - return (depth == CV_8U || depth == CV_16U); - } - --bool AvifEncoder::write(const Mat &img, const std::vector ¶ms) { -- std::vector img_vec(1, img); -- return writemulti(img_vec, params); --} -- - bool AvifEncoder::writeanimation(const Animation& animation, - const std::vector ¶ms) { - int bit_depth = 8; -diff --git a/modules/imgcodecs/src/grfmt_avif.hpp b/modules/imgcodecs/src/grfmt_avif.hpp -index 87b765619e..9f097aaf55 100644 ---- a/modules/imgcodecs/src/grfmt_avif.hpp -+++ b/modules/imgcodecs/src/grfmt_avif.hpp -@@ -41,7 +41,6 @@ class AvifEncoder CV_FINAL : public BaseImageEncoder { - ~AvifEncoder() CV_OVERRIDE; - - bool isFormatSupported(int depth) const CV_OVERRIDE; -- bool write(const Mat& img, const std::vector& params) CV_OVERRIDE; - bool writeanimation(const Animation& animation, const std::vector& params) CV_OVERRIDE; - - ImageEncoder newEncoder() const CV_OVERRIDE; -diff --git a/modules/imgcodecs/src/grfmt_base.cpp b/modules/imgcodecs/src/grfmt_base.cpp -index 1e09882780..dc3d07ab78 100644 ---- a/modules/imgcodecs/src/grfmt_base.cpp -+++ b/modules/imgcodecs/src/grfmt_base.cpp -@@ -140,6 +140,11 @@ bool BaseImageEncoder::setDestination( std::vector& buf ) - return true; - } - -+bool BaseImageEncoder::write(const Mat &img, const std::vector ¶ms) { -+ std::vector img_vec(1, img); -+ return writemulti(img_vec, params); -+} -+ - bool BaseImageEncoder::writemulti(const std::vector& img_vec, const std::vector& params) - { - if(img_vec.size() > 1) -@@ -157,6 +162,7 @@ bool BaseImageEncoder::writemulti(const std::vector& img_vec, const std::ve - - bool BaseImageEncoder::writeanimation(const Animation&, const std::vector& ) - { -+ CV_LOG_WARNING(NULL, "No Animation encoder for specified file extension"); - return false; - } - -@@ -165,7 +171,7 @@ ImageEncoder BaseImageEncoder::newEncoder() const - return ImageEncoder(); - } - --void BaseImageEncoder::throwOnEror() const -+void BaseImageEncoder::throwOnError() const - { - if(!m_last_error.empty()) - { -diff --git a/modules/imgcodecs/src/grfmt_base.hpp b/modules/imgcodecs/src/grfmt_base.hpp -index a90bd8a3de..ae5622528c 100644 ---- a/modules/imgcodecs/src/grfmt_base.hpp -+++ b/modules/imgcodecs/src/grfmt_base.hpp -@@ -202,12 +202,11 @@ public: - - /** - * @brief Encode and write the image data. -- * This is a pure virtual function that must be implemented by derived classes. - * @param img The Mat object containing the image data to be encoded. - * @param params A vector of parameters controlling the encoding process (e.g., compression level). - * @return true if the image was successfully written, false otherwise. - */ -- virtual bool write(const Mat& img, const std::vector& params) = 0; -+ virtual bool write(const Mat& img, const std::vector& params); - - /** - * @brief Encode and write multiple images (e.g., for animated formats). -@@ -236,7 +235,7 @@ public: - * @brief Throw an exception based on the last error encountered during encoding. - * This method can be used to propagate error conditions back to the caller. - */ -- virtual void throwOnEror() const; -+ virtual void throwOnError() const; - - protected: - String m_description; ///< Description of the encoder (e.g., format name, capabilities). -diff --git a/modules/imgcodecs/src/grfmt_gif.cpp b/modules/imgcodecs/src/grfmt_gif.cpp -index 5a65ae04b1..b0533b644f 100644 ---- a/modules/imgcodecs/src/grfmt_gif.cpp -+++ b/modules/imgcodecs/src/grfmt_gif.cpp -@@ -488,19 +488,11 @@ GifEncoder::~GifEncoder() { - close(); - } - --bool GifEncoder::isFormatSupported(int depth) const { -- return depth == CV_8U; --} -- --bool GifEncoder::write(const Mat &img, const std::vector ¶ms) { -- std::vector img_vec(1, img); -- return writemulti(img_vec, params); --} -- - bool GifEncoder::writeanimation(const Animation& animation, const std::vector& params) { - if (animation.frames.empty()) { - return false; - } -+ CV_CheckDepthEQ(animation.frames[0].depth(), CV_8U, "GIF encoder supports only 8-bit unsigned images"); - - if (m_buf) { - if (!strm.open(*m_buf)) { -diff --git a/modules/imgcodecs/src/grfmt_gif.hpp b/modules/imgcodecs/src/grfmt_gif.hpp -index 8f520745ba..8552718d00 100644 ---- a/modules/imgcodecs/src/grfmt_gif.hpp -+++ b/modules/imgcodecs/src/grfmt_gif.hpp -@@ -83,9 +83,6 @@ public: - GifEncoder(); - ~GifEncoder() CV_OVERRIDE; - -- bool isFormatSupported(int depth) const CV_OVERRIDE; -- -- bool write(const Mat& img, const std::vector& params) CV_OVERRIDE; - bool writeanimation(const Animation& animation, const std::vector& params) CV_OVERRIDE; - - ImageEncoder newEncoder() const CV_OVERRIDE; -diff --git a/modules/imgcodecs/src/grfmt_png.cpp b/modules/imgcodecs/src/grfmt_png.cpp -index f7a19c2bf5..825122304a 100644 ---- a/modules/imgcodecs/src/grfmt_png.cpp -+++ b/modules/imgcodecs/src/grfmt_png.cpp -@@ -1412,6 +1412,9 @@ void PngEncoder::deflateRectFin(unsigned char* zbuf, uint32_t* zsize, int bpp, i - - bool PngEncoder::writeanimation(const Animation& animation, const std::vector& params) - { -+ int frame_type = animation.frames[0].type(); -+ int frame_depth = animation.frames[0].depth(); -+ CV_CheckType(frame_type, frame_depth == CV_8U || frame_depth == CV_16U, "APNG decoder supports only 8 or 16 bit unsigned images"); - int compression_level = 6; - int compression_strategy = IMWRITE_PNG_STRATEGY_RLE; // Default strategy - bool isBilevel = false; -@@ -1435,7 +1438,8 @@ bool PngEncoder::writeanimation(const Animation& animation, const std::vectorwritemulti(write_vec, params); - -- encoder->throwOnEror(); -+ encoder->throwOnError(); - CV_Assert( code ); - } - catch (const cv::Exception& e) --- -2.48.1 - diff --git a/0010-Merge-pull-request-26915-from-mshabunin-fix-png-be.patch b/0010-Merge-pull-request-26915-from-mshabunin-fix-png-be.patch deleted file mode 100644 index 17f4955..0000000 --- a/0010-Merge-pull-request-26915-from-mshabunin-fix-png-be.patch +++ /dev/null @@ -1,54 +0,0 @@ -From ab0a4167057dadcfc497f0d4d653b5eec7fd586a Mon Sep 17 00:00:00 2001 -From: Maksim Shabunin -Date: Thu, 13 Feb 2025 16:58:15 +0300 -Subject: [PATCH 10/10] Merge pull request #26915 from mshabunin:fix-png-be - -Resolves #26913 -Related(?): #25715 #26832 ---- - modules/imgcodecs/src/grfmt_png.cpp | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - -diff --git a/modules/imgcodecs/src/grfmt_png.cpp b/modules/imgcodecs/src/grfmt_png.cpp -index 825122304a..84df975471 100644 ---- a/modules/imgcodecs/src/grfmt_png.cpp -+++ b/modules/imgcodecs/src/grfmt_png.cpp -@@ -121,16 +121,16 @@ - namespace cv - { - --const uint32_t id_IHDR = 0x52444849; // PNG header --const uint32_t id_acTL = 0x4C546361; // Animation control chunk --const uint32_t id_fcTL = 0x4C546366; // Frame control chunk --const uint32_t id_IDAT = 0x54414449; // first frame and/or default image --const uint32_t id_fdAT = 0x54416466; // Frame data chunk --const uint32_t id_PLTE = 0x45544C50; // The PLTE chunk contains a color palette for indexed-color images --const uint32_t id_bKGD = 0x44474B62; // The bKGD chunk specifies a default background color for the image --const uint32_t id_tRNS = 0x534E5274; // The tRNS chunk provides transparency information --const uint32_t id_tEXt = 0x74584574; // The tEXt chunk stores metadata as text in key-value pairs --const uint32_t id_IEND = 0x444E4549; // end/footer chunk -+const uint32_t id_IHDR = 0x49484452; // PNG header -+const uint32_t id_acTL = 0x6163544C; // Animation control chunk -+const uint32_t id_fcTL = 0x6663544C; // Frame control chunk -+const uint32_t id_IDAT = 0x49444154; // first frame and/or default image -+const uint32_t id_fdAT = 0x66644154; // Frame data chunk -+const uint32_t id_PLTE = 0x504C5445; // The PLTE chunk contains a color palette for indexed-color images -+const uint32_t id_bKGD = 0x624B4744; // The bKGD chunk specifies a default background color for the image -+const uint32_t id_tRNS = 0x74524E53; // The tRNS chunk provides transparency information -+const uint32_t id_tEXt = 0x74455874; // The tEXt chunk stores metadata as text in key-value pairs -+const uint32_t id_IEND = 0x49454E44; // end/footer chunk - - APNGFrame::APNGFrame() - { -@@ -699,7 +699,7 @@ uint32_t PngDecoder::read_chunk(Chunk& chunk) - return 0; - const size_t size = static_cast(png_get_uint_32(size_id)) + 12; - -- const uint32_t id = *(uint32_t*)(&size_id[4]); -+ const uint32_t id = png_get_uint_32(size_id + 4); - if (id == id_IHDR) { - // 8=HDR+size, 13=size of IHDR chunk, 4=CRC - // http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.IHDR --- -2.48.1 - diff --git a/26750.patch b/26750.patch deleted file mode 100644 index 4a2fdc0..0000000 --- a/26750.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 97f3f390661f2fd1168336820b89eb4383ce8528 Mon Sep 17 00:00:00 2001 -From: Maksim Shabunin -Date: Fri, 10 Jan 2025 18:34:11 +0300 -Subject: [PATCH] core: fixed VSX intrinsics implementation - ---- - modules/core/include/opencv2/core/hal/intrin_vsx.hpp | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/modules/core/include/opencv2/core/hal/intrin_vsx.hpp b/modules/core/include/opencv2/core/hal/intrin_vsx.hpp -index 2157e1e87063..0a0915a22fc4 100644 ---- a/modules/core/include/opencv2/core/hal/intrin_vsx.hpp -+++ b/modules/core/include/opencv2/core/hal/intrin_vsx.hpp -@@ -262,7 +262,7 @@ OPENCV_HAL_IMPL_VSX_EXTRACT_N(v_float64x2, double) - inline _Tpvec v_setzero_##suffix() { return _Tpvec(vec_splats((_Tp)0)); } \ - inline _Tpvec v_setall_##suffix(_Tp v) { return _Tpvec(vec_splats((_Tp)v));} \ - template <> inline _Tpvec v_setzero_() { return v_setzero_##suffix(); } \ --template <> inline _Tpvec v_setall_(_Tp v) { return v_setall_##suffix(_Tp v); } \ -+template <> inline _Tpvec v_setall_(_Tp v) { return v_setall_##suffix(v); } \ - template inline _Tpvec v_reinterpret_as_##suffix(const _Tpvec0 &a) \ - { return _Tpvec((cast)a.val); } - -@@ -650,11 +650,11 @@ OPENCV_HAL_IMPL_VSX_SELECT(v_float64x2, vec_bdword2_c) - #define OPENCV_HAL_IMPL_VSX_INT_CMP_OP(_Tpvec) \ - inline _Tpvec v_eq(const _Tpvec& a, const _Tpvec& b) \ - { return _Tpvec(vec_cmpeq(a.val, b.val)); } \ --inline _Tpvec V_ne(const _Tpvec& a, const _Tpvec& b) \ -+inline _Tpvec v_ne(const _Tpvec& a, const _Tpvec& b) \ - { return _Tpvec(vec_cmpne(a.val, b.val)); } \ - inline _Tpvec v_lt(const _Tpvec& a, const _Tpvec& b) \ - { return _Tpvec(vec_cmplt(a.val, b.val)); } \ --inline _Tpvec V_gt(const _Tpvec& a, const _Tpvec& b) \ -+inline _Tpvec v_gt(const _Tpvec& a, const _Tpvec& b) \ - { return _Tpvec(vec_cmpgt(a.val, b.val)); } \ - inline _Tpvec v_le(const _Tpvec& a, const _Tpvec& b) \ - { return _Tpvec(vec_cmple(a.val, b.val)); } \ -@@ -1507,7 +1507,7 @@ inline v_float64x2 v_dotprod_expand(const v_int32x4& a, const v_int32x4& b, cons - inline v_int32x4 v_dotprod_fast(const v_int16x8& a, const v_int16x8& b) - { return v_dotprod(a, b); } - inline v_int32x4 v_dotprod_fast(const v_int16x8& a, const v_int16x8& b, const v_int32x4& c) --{ return v_int32x4(vec_msum(a.val, b.val, vec_int4_z)) + c; } -+{ return v_add(v_int32x4(vec_msum(a.val, b.val, vec_int4_z)), c); } - // 32 >> 64 - inline v_int64x2 v_dotprod_fast(const v_int32x4& a, const v_int32x4& b) - { return v_dotprod(a, b); } -@@ -1518,7 +1518,7 @@ inline v_int64x2 v_dotprod_fast(const v_int32x4& a, const v_int32x4& b, const v_ - inline v_uint32x4 v_dotprod_expand_fast(const v_uint8x16& a, const v_uint8x16& b) - { return v_dotprod_expand(a, b); } - inline v_uint32x4 v_dotprod_expand_fast(const v_uint8x16& a, const v_uint8x16& b, const v_uint32x4& c) --{ return v_uint32x4(vec_msum(a.val, b.val, vec_uint4_z)) + c; } -+{ return v_add(v_uint32x4(vec_msum(a.val, b.val, vec_uint4_z)), c); } - - inline v_int32x4 v_dotprod_expand_fast(const v_int8x16& a, const v_int8x16& b) - { diff --git a/26786.patch b/26786.patch deleted file mode 100644 index 3ae3d3e..0000000 --- a/26786.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 63ef786a3a0afcd44bf842f967656052d52dde09 Mon Sep 17 00:00:00 2001 -From: Maksim Shabunin -Date: Thu, 16 Jan 2025 23:48:29 +0300 -Subject: [PATCH] core: fixed VSX build with GCC 15 - ---- - modules/core/include/opencv2/core/vsx_utils.hpp | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/modules/core/include/opencv2/core/vsx_utils.hpp b/modules/core/include/opencv2/core/vsx_utils.hpp -index 79a1074d59ff..4d5a694bae8e 100644 ---- a/modules/core/include/opencv2/core/vsx_utils.hpp -+++ b/modules/core/include/opencv2/core/vsx_utils.hpp -@@ -257,8 +257,8 @@ VSX_IMPL_1VRG(vec_udword2, vec_udword2, vpopcntd, vec_popcntu) - VSX_IMPL_1VRG(vec_udword2, vec_dword2, vpopcntd, vec_popcntu) - - // converts between single and double-precision --VSX_REDIRECT_1RG(vec_float4, vec_double2, vec_cvfo, __builtin_vsx_xvcvdpsp) --VSX_REDIRECT_1RG(vec_double2, vec_float4, vec_cvfo, __builtin_vsx_xvcvspdp) -+VSX_REDIRECT_1RG(vec_float4, vec_double2, vec_cvfo, vec_floate) -+VSX_REDIRECT_1RG(vec_double2, vec_float4, vec_cvfo, vec_doubleo) - - // converts word and doubleword to double-precision - #undef vec_ctd -@@ -399,10 +399,6 @@ VSX_REDIRECT_1RG(vec_ushort8, vec_ushort8, vec_popcntu, vec_popcnt) - VSX_REDIRECT_1RG(vec_uint4, vec_uint4, vec_popcntu, vec_popcnt) - VSX_REDIRECT_1RG(vec_udword2, vec_udword2, vec_popcntu, vec_popcnt) - --// converts between single and double precision --VSX_REDIRECT_1RG(vec_float4, vec_double2, vec_cvfo, __builtin_vsx_xvcvdpsp) --VSX_REDIRECT_1RG(vec_double2, vec_float4, vec_cvfo, __builtin_vsx_xvcvspdp) -- - // converts word and doubleword to double-precision - #ifdef vec_ctd - # undef vec_ctd diff --git a/27536.patch b/27536.patch deleted file mode 100644 index 0b7a4ce..0000000 --- a/27536.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 353b4ddf52db48ba85d2efaa33310afa0eb73a72 Mon Sep 17 00:00:00 2001 -From: Kumataro -Date: Sun, 13 Jul 2025 08:11:06 +0900 -Subject: [PATCH 1/2] eigen: fix to get version from eigen master branch - ---- - cmake/OpenCVFindLibsPerf.cmake | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/cmake/OpenCVFindLibsPerf.cmake b/cmake/OpenCVFindLibsPerf.cmake -index dfc94597bbba..55a08f72d00d 100644 ---- a/cmake/OpenCVFindLibsPerf.cmake -+++ b/cmake/OpenCVFindLibsPerf.cmake -@@ -84,6 +84,12 @@ if(WITH_EIGEN AND NOT HAVE_EIGEN) - set(EIGEN_WORLD_VERSION ${EIGEN3_WORLD_VERSION}) - set(EIGEN_MAJOR_VERSION ${EIGEN3_MAJOR_VERSION}) - set(EIGEN_MINOR_VERSION ${EIGEN3_MINOR_VERSION}) -+ elseif(DEFINED Eigen3_VERSION_MAJOR) -+ # see https://github.com/opencv/opencv/issues/27530 -+ # Case sensitive is needed to support Eigen on Master branch at 13 July,2025. -+ set(EIGEN_WORLD_VERSION ${Eigen3_VERSION_MAJOR}) -+ set(EIGEN_MAJOR_VERSION ${Eigen3_VERSION_MINOR}) -+ set(EIGEN_MINOR_VERSION ${Eigen3_VERSION_PATCH}) - else() # Eigen config file - set(EIGEN_WORLD_VERSION ${EIGEN3_VERSION_MAJOR}) - set(EIGEN_MAJOR_VERSION ${EIGEN3_VERSION_MINOR}) - -From 94e909d4a6811bbd4774baae8722df79d057a2bc Mon Sep 17 00:00:00 2001 -From: Kumataro -Date: Mon, 14 Jul 2025 21:25:52 +0900 -Subject: [PATCH 2/2] add pointer to Eigen commit - ---- - cmake/OpenCVFindLibsPerf.cmake | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/cmake/OpenCVFindLibsPerf.cmake b/cmake/OpenCVFindLibsPerf.cmake -index 55a08f72d00d..861a39c47f9b 100644 ---- a/cmake/OpenCVFindLibsPerf.cmake -+++ b/cmake/OpenCVFindLibsPerf.cmake -@@ -84,13 +84,13 @@ if(WITH_EIGEN AND NOT HAVE_EIGEN) - set(EIGEN_WORLD_VERSION ${EIGEN3_WORLD_VERSION}) - set(EIGEN_MAJOR_VERSION ${EIGEN3_MAJOR_VERSION}) - set(EIGEN_MINOR_VERSION ${EIGEN3_MINOR_VERSION}) -- elseif(DEFINED Eigen3_VERSION_MAJOR) -+ elseif(DEFINED Eigen3_VERSION_MAJOR) # Recommended package config variables - # see https://github.com/opencv/opencv/issues/27530 -- # Case sensitive is needed to support Eigen on Master branch at 13 July,2025. - set(EIGEN_WORLD_VERSION ${Eigen3_VERSION_MAJOR}) - set(EIGEN_MAJOR_VERSION ${Eigen3_VERSION_MINOR}) - set(EIGEN_MINOR_VERSION ${Eigen3_VERSION_PATCH}) -- else() # Eigen config file -+ else() # Deprecated package config variables -+ # Removed on master at https://gitlab.com/libeigen/eigen/-/commit/f2984cd0778dd0a1d7e74216d826eaff2bc6bfab - set(EIGEN_WORLD_VERSION ${EIGEN3_VERSION_MAJOR}) - set(EIGEN_MAJOR_VERSION ${EIGEN3_VERSION_MINOR}) - set(EIGEN_MINOR_VERSION ${EIGEN3_VERSION_PATCH}) diff --git a/27691.patch b/27691.patch deleted file mode 100644 index c08b882..0000000 --- a/27691.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 90c444abd387ffa70b2e72a34922903a2f0f4f5a Mon Sep 17 00:00:00 2001 -From: Alexander Smorkalov -Date: Wed, 20 Aug 2025 10:53:51 +0300 -Subject: [PATCH] FFmpeg 8.0 support. - ---- - modules/videoio/src/cap_ffmpeg_impl.hpp | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp -index 489dbe565d3d..5780b4c11361 100644 ---- a/modules/videoio/src/cap_ffmpeg_impl.hpp -+++ b/modules/videoio/src/cap_ffmpeg_impl.hpp -@@ -685,7 +685,10 @@ void CvCapture_FFMPEG::close() - if( video_st ) - { - #ifdef CV_FFMPEG_CODECPAR -+// avcodec_close removed in FFmpeg release 8.0 -+# if (LIBAVCODEC_BUILD < CALC_FFMPEG_VERSION(62, 11, 100)) - avcodec_close( context ); -+# endif - #endif - video_st = NULL; - } -@@ -2005,7 +2008,18 @@ void CvCapture_FFMPEG::get_rotation_angle() - rotation_angle = 0; - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(57, 68, 100) - const uint8_t *data = 0; -+ // av_stream_get_side_data removed in FFmpeg release 8.0 -+# if (LIBAVCODEC_BUILD < CALC_FFMPEG_VERSION(62, 11, 100)) - data = av_stream_get_side_data(video_st, AV_PKT_DATA_DISPLAYMATRIX, NULL); -+# else -+ AVPacketSideData* sd = video_st->codecpar->coded_side_data; -+ int nb_sd = video_st->codecpar->nb_coded_side_data; -+ if (sd && nb_sd > 0) -+ { -+ const AVPacketSideData* mtx = av_packet_side_data_get(sd, nb_sd, AV_PKT_DATA_DISPLAYMATRIX); -+ data = mtx->data; -+ } -+# endif - if (data) - { - rotation_angle = -cvRound(av_display_rotation_get((const int32_t*)data)); diff --git a/README.packit b/README.packit index 8c905b9..d2b528d 100644 --- a/README.packit +++ b/README.packit @@ -1,3 +1,3 @@ This repository is maintained by packit. https://packit.dev/ -The file was generated using packit 0.106.0.post1.dev8+g521f1e1d. +The file was generated using packit 0.97.1.post1.dev6+gc8c0314a. diff --git a/opencv-clean.sh b/opencv-clean.sh index 4c44f46..df36b0c 100755 --- a/opencv-clean.sh +++ b/opencv-clean.sh @@ -1,6 +1,6 @@ #!/bin/bash -VERSION=$1 +VERSION=4.9.0 wget -c https://github.com/opencv/opencv/archive/${VERSION}/opencv-${VERSION}.tar.gz wget -c https://github.com/opencv/opencv_contrib/archive/${VERSION}/opencv_contrib-${VERSION}.tar.gz @@ -31,4 +31,4 @@ tar zcf opencv_extra-clean-${VERSION}.tar.gz opencv_extra-${VERSION}/ rm -r opencv_extra-${VERSION}/ -#echo fedpkg new-sources $(spectool -l --sources opencv.spec | sed 's/.*: //;s/.*\///') +echo fedpkg new-sources $(spectool -l --sources opencv.spec | sed 's/.*: //;s/.*\///') diff --git a/opencv.spec b/opencv.spec index c197a96..8f78ddd 100644 --- a/opencv.spec +++ b/opencv.spec @@ -1,3 +1,5 @@ +%undefine __cmake_in_source_build + %bcond_with tests %bcond_without compat_openvc_pc %if %{without tests} @@ -9,6 +11,7 @@ %bcond_with linters %bcond_without ffmpeg %bcond_without gstreamer +%bcond_with eigen2 %bcond_without eigen3 %bcond_without opencl %ifarch x86_64 %{arm} @@ -22,10 +25,9 @@ %bcond_without xine # Atlas need (missing: Atlas_CLAPACK_INCLUDE_DIR Atlas_CBLAS_LIBRARY Atlas_BLAS_LIBRARY Atlas_LAPACK_LIBRARY) # LAPACK may use atlas or openblas since now it detect openblas, atlas is not used anyway, more info please -# Now FlexiBLAS should be used instead: https://fedoraproject.org/wiki/Changes/FlexiBLAS_as_BLAS/LAPACK_manager +# check OpenCVFindLAPACK.cmake %bcond_with atlas -%bcond_with openblas -%bcond_without flexiblas +%bcond_without openblas %bcond_without gdcm %if 0%{?rhel} >= 8 %bcond_with vtk @@ -55,7 +57,7 @@ %bcond_with openexr %endif -%bcond_without libva +%bcond_without va %bcond_without vulkan %define _lto_cflags %{nil} @@ -69,13 +71,13 @@ %endif Name: opencv -Version: 4.12.0 +Version: 4.10.0 %global javaver %(foo=%{version}; echo ${foo//./}) %global majorver %(foo=%{version}; a=(${foo//./ }); echo ${a[0]} ) %global minorver %(foo=%{version}; a=(${foo//./ }); echo ${a[1]} ) %global padding %(digits=00; num=%{minorver}; echo ${digits:${#num}:${#digits}} ) %global abiver %(echo %{majorver}%{padding}%{minorver} ) -Release: 20%{?dist} +Release: 8%{?dist} Summary: Collection of algorithms for computer vision # This is normal three clause BSD. License: BSD-3-Clause AND Apache-2.0 AND ISC @@ -93,7 +95,7 @@ Source1: %{name}_contrib-clean-%{version}.tar.gz } Source3: face_landmark_model.dat.xz # SRC=v0.1.2d.zip ; wget https://github.com/opencv/ade/archive/$SRC; mv $SRC $(md5sum $SRC | cut -d' ' -f1)-$SRC -Source4: 962ce79e0b95591f226431f7b5f152cd-v0.1.2e.zip +Source4: dbb095a8bf3008e91edbbf45d8d34885-v0.1.2d.zip Source5: xorg.conf %global wechat_commit 3487ef7cde71d93c6a01bb0b84aa0f22c6128f6b %global wechat_shortcommit %(c=%{wechat_commit}; echo ${c:0:7}) @@ -102,14 +104,6 @@ Source6: https://github.com/WeChatCV/opencv_3rdparty/archive/%{wechat_com Patch0: opencv-4.1.0-install_3rdparty_licenses.patch Patch3: opencv.python.patch -# Fix build with Qt 6.9, by Atri Bhattacharya (thanks) -# https://github.com/opencv/opencv/issues/27223#issuecomment-2797750952 -Patch16: qt69.patch -# Fix build with FFmpeg 8 -Patch17: https://github.com/opencv/opencv/pull/27691.patch -# Fix detect Eigen3 > 3 -Patch18: https://github.com/opencv/opencv/pull/27536.patch - BuildRequires: gcc-c++ BuildRequires: cmake >= 2.6.3 @@ -121,6 +115,7 @@ BuildRequires: pkgconfig(cufft-%{?_cuda_version}) BuildRequires: pkgconfig(nppc-%{?_cuda_version}) %{?with_dnn_cuda:BuildRequires: libcudnn8-devel} } +%{?with_eigen2:BuildRequires: eigen2-devel} %{?with_eigen3:BuildRequires: eigen3-devel} BuildRequires: libtheora-devel BuildRequires: libvorbis-devel @@ -131,7 +126,6 @@ BuildRequires: libdc1394-devel %endif %endif BuildRequires: jasper-devel -BuildRequires: pkgconfig(libavif) BuildRequires: libjpeg-devel BuildRequires: libpng-devel BuildRequires: libtiff-devel @@ -142,7 +136,7 @@ BuildRequires: OpenEXR-devel } %{?with_openni: BuildRequires: openni-devel -%if 0%{?fedora} && 0%{?fedora} < 44 +%if 0%{?fedora} BuildRequires: openni-primesense %endif } @@ -153,6 +147,7 @@ BuildRequires: zlib-devel BuildRequires: pkgconfig BuildRequires: python3-devel BuildRequires: python3-numpy +BuildRequires: python3-setuptools %{?with_linters: BuildRequires: pylint BuildRequires: python3-flake8 @@ -199,6 +194,7 @@ BuildRequires: harfbuzz-devel BuildRequires: vtk-java } } +%{?with_atlas:BuildRequires: atlas-devel} #ceres-solver-devel push eigen3-devel and tbb-devel %{?with_tbb: %{?with_eigen3: @@ -207,22 +203,21 @@ BuildRequires: vtk-java # BuildRequires: ceres-solver-devel } } -%{?with_atlas:BuildRequires: atlas-devel} -%{?with_openblas:BuildRequires: openblas-devel} -%{?with_flexiblas:BuildRequires: flexiblas-devel} +%{?with_openblas: +BuildRequires: openblas-devel +BuildRequires: blas-devel +BuildRequires: lapack-devel +} %{?with_gdcm:BuildRequires: gdcm-devel} %{?with_libmfx:BuildRequires: libvpl-devel} %{?with_clp:BuildRequires: coin-or-Clp-devel} -%{?with_libva:BuildRequires: libva-devel} +%{?with_va:BuildRequires: libva-devel} %{?with_java: BuildRequires: ant BuildRequires: java-devel } %{?with_vulkan:BuildRequires: vulkan-headers} -%ifnarch i686 -BuildRequires: flatbuffers-devel -BuildRequires: flatbuffers-compiler -%endif +#BuildRequires: flatbuffers-devel %if %{with tests} BuildRequires: xorg-x11-drv-dummy BuildRequires: mesa-dri-drivers @@ -289,9 +284,7 @@ This package contains the OpenCV %{moduledesc} module runtime.\ %opencv_module_subpkg -m video -d %{quote:Video Analysis} %opencv_module_subpkg -m videoio -d %{quote:Video I/O} # contrib/extra modules -%if %{with eigen3} %opencv_module_subpkg -m alphamat -d %{quote:Alpha Matting} -%endif %opencv_module_subpkg -m aruco -d %{quote:Aruco Markers} %opencv_module_subpkg -m bgsegm -d %{quote:Background Segmentation} %opencv_module_subpkg -m bioinspired -d %{quote:Biologically-inspired Vision Models} @@ -411,9 +404,6 @@ popd &>/dev/null %patch -P 0 -p1 -b .install_3rdparty_licenses %patch -P 3 -p1 -b .python_install_binary -%patch -P 16 -p1 -b .qt69 -%patch -P 17 -p1 -b .ffmpeg8 -%patch -P 18 -p1 -b .eigen3 pushd %{name}_contrib-%{version} #patch1 -p1 -b .install_cvv @@ -436,20 +426,14 @@ mv opencv_3rdparty-%{wechat_commit}/sr.prototxt .cache/wechat_qrcode/69db99927a7 mkdir -p .cache/ade install -pm 0644 %{S:4} .cache/ade/ -%generate_buildrequires -cd modules/python/package -%pyproject_buildrequires - %build -# TODO: Please submit an issue to upstream (rhbz#2381337) -export CMAKE_POLICY_VERSION_MINIMUM=3.5 # enabled by default if libraries are presents at build time: # GTK, GSTREAMER, 1394, V4L, eigen3 # non available on Fedora: FFMPEG, XINE # disabling IPP because it is closed source library from intel %cmake \ -%if 0%{?fedora} > 38 || 0%{?rhel} > 10 +%if 0%{?fedora} > 38 -DCMAKE_CXX_STANDARD=17 \ %endif -DCV_TRACE=OFF \ @@ -468,9 +452,6 @@ export CMAKE_POLICY_VERSION_MINIMUM=3.5 -DWITH_CAROTENE=OFF \ %ifarch x86_64 %{ix86} -DCPU_BASELINE=SSE2 \ -%ifarch %{ix86} - -DCPU_DISPATCH=SSE4_2 \ -%endif %endif -DCMAKE_BUILD_TYPE=Release \ %{?with_java: -DBUILD_opencv_java=ON \ @@ -495,6 +476,7 @@ export CMAKE_POLICY_VERSION_MINIMUM=3.5 -DINSTALL_C_EXAMPLES=ON \ -DINSTALL_PYTHON_EXAMPLES=ON \ -DPYTHON3_EXECUTABLE=%{__python3} \ + -DPYTHON3_PACKAGES_PATH=%{python3_sitearch} \ -DOPENCV_GENERATE_SETUPVARS=OFF \ %{!?with_linters: \ -DENABLE_PYLINT=OFF \ @@ -510,35 +492,20 @@ export CMAKE_POLICY_VERSION_MINIMUM=3.5 -DOPENCV_CONFIG_INSTALL_PATH=%{_lib}/cmake/OpenCV \ -DOPENCV_GENERATE_PKGCONFIG=ON \ %{?with_extras_tests: -DOPENCV_TEST_DATA_PATH=opencv_extra-%{version}/testdata} \ - %{?without_eigen3: -DWITH_EIGEN=OFF} \ %{?with_gdcm: -DWITH_GDCM=ON } \ - -DWITH_IMGCODEC_GIF=ON \ %{?with_libmfx: -DWITH_MFX=ON -DWITH_GAPI_ONEVPL=ON} \ %{?with_clp: -DWITH_CLP=ON } \ - %{?with_libva: -DWITH_VA=ON } \ + %{?with_va: -DWITH_VA=ON } \ %{!?with_vtk: -DWITH_VTK=OFF} \ %{?with_vulkan: -DWITH_VULKAN=ON -DVULKAN_INCLUDE_DIRS=%{_includedir}/vulkan } %cmake_build -cd %{__cmake_builddir}/python_loader/ -%pyproject_wheel %install %cmake_install cd %{__cmake_builddir}/python_loader/ -%pyproject_install -%pyproject_save_files cv2 -# Hack - move the binary -%ifnarch i686 -mkdir -p %{buildroot}/%{python3_sitearch}/cv2 -mv %{buildroot}/%{python3_sitelib}/cv2/cv2.cpython-*-linux-gnu.so \ - %{buildroot}/%{python3_sitearch}/cv2 -%endif -# Correct reference in config-x.yz, keep build one for testing -mkdir test_python -cp %{buildroot}/%{python3_sitelib}/cv2/config-*.py test_python -sed -i -e "s#/builddir[^']*#%{python3_sitearch}/cv2#g" %{buildroot}/%{python3_sitelib}/cv2/config-*.py +%py3_install -- --install-lib %{python3_sitearch} rm -rf %{buildroot}%{_datadir}/OpenCV/licenses/ %if %{with java} @@ -553,14 +520,6 @@ ln -s -r %{buildroot}%{_jnidir}/opencv-%{javaver}.jar %{buildroot}%{_jnidir}/ope %check -export LD_LIBRARY_PATH=%{_builddir}/%{name}-%{version}/%{__cmake_builddir}/lib:$LD_LIBARY_PATH -# Due to complex import method, we need to point to builddir temporarily at least to have test working, undoing -# the fix above and then removing this again -cp %{buildroot}/%{python3_sitelib}/cv2/config-*.py . -cp %{__cmake_builddir}/python_loader/test_python/config-*.py %{buildroot}/%{python3_sitelib}/cv2/ -%pyproject_check_import -e cv2.config -cp config-*.py %{buildroot}/%{python3_sitelib}/cv2/ - #ifnarch ppc64 %if %{with tests} cp %{S:5} %{__cmake_builddir} @@ -571,6 +530,7 @@ cp config-*.py %{buildroot}/%{python3_sitelib}/cv2/ fi $Xorg -noreset +extension GLX +extension RANDR +extension RENDER -logfile ./xorg.log -config ./xorg.conf -configdir . :99 & export DISPLAY=:99 + export LD_LIBRARY_PATH=%{_builddir}/%{name}-%{version}/%{__cmake_builddir}/lib:$LD_LIBARY_PATH %ctest || : %endif #endif @@ -606,14 +566,9 @@ cp config-*.py %{buildroot}/%{python3_sitelib}/cv2/ %files doc %{_datadir}/opencv4/samples -# some files aren't properly listed -#files -n python3-opencv -f %%{pyproject_files} %files -n python3-opencv -%{python3_sitelib}/opencv*.dist-info -%{python3_sitelib}/cv2 -%ifnarch i686 %{python3_sitearch}/cv2 -%endif +%{python3_sitearch}/opencv-*.egg-info %if %{with java} %files java @@ -625,76 +580,8 @@ cp config-*.py %{buildroot}/%{python3_sitelib}/cv2/ %changelog -* Sun Nov 23 2025 Sandro Mani - 4.11.0-20 -- Rebuild (gdal) - -* Tue Nov 11 2025 Cristian Le - 4.11.0-19 -- Allow to build with CMake 4.0 (rhbz#2381337) - -* Wed Nov 05 2025 Dominik Mierzejewski - 4.11.0-18 -- Rebuilt for FFmpeg 8 - -* Wed Oct 29 2025 Federico Pellegrin - 4.11.0-17 -- Fix importing of Python module (#2406800) - -* Mon Oct 20 2025 Nicolas Chauvet - 4.11.0-16 -- Fix build with i686 - -* Mon Oct 20 2025 Iñaki Úcar - 4.11.0-15 -- https://fedoraproject.org/wiki/Changes/FlexiBLAS_as_BLAS/LAPACK_manager - -* Fri Oct 17 2025 Dominik Mierzejewski - 4.11.0-14 -- Fix build with FFmpeg 8 - -* Thu Oct 16 2025 Nicolas Chauvet - 4.11.0-13 -- Use pyprojectize - thanks Miro ! - -* Tue Sep 30 2025 Nicolas Chauvet - 4.11.0-12 -- Drop retired openni-primesense in fedora >= 44 - -* Fri Sep 19 2025 Python Maint - 4.11.0-11 -- Rebuilt for Python 3.14.0rc3 bytecode - -* Sun Aug 24 2025 Orion Poplawski - 4.11.0-10 -- Rebuild for VTK 9.5 - -* Wed Aug 20 2025 Jerry James - 4.11.0-9 -- Rebuild for tbb 2022.2.0 - -* Fri Aug 15 2025 Python Maint - 4.11.0-8 -- Rebuilt for Python 3.14.0rc2 bytecode - -* Thu Jul 31 2025 Adam Williamson - 4.11.0-7 -- Rebuild for new gdal - -* Tue Jul 29 2025 Nicolas Chauvet - 4.11.0-6 -- Add missing BR libavif - -* Thu Jul 24 2025 Fedora Release Engineering - 4.11.0-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild - -* Tue Jul 08 2025 Adam Williamson - 4.11.0-4 -- Rebuilt for Python 3.14 -- Add patch from Atri Bhattacharya to fix build with Qt 6.9 - -* Tue Mar 11 2025 Yaakov Selkowitz - 4.11.0-3 -- Use Qt6 in highgui and cvv - -* Tue Feb 18 2025 Adam Williamson - 4.11.0-2 -- Backport all post-4.11.0 PNG fixes, including big-endian fix -- Resolves: rhbz#2345306 - -* Mon Feb 03 2025 Sérgio Basto 4.11.0-1 -- Update to version 4.11.0 -- Resolves: rhbz#2336422 -- Add upstream patch to fix build on PPC64LE - -* Fri Jan 17 2025 Fedora Release Engineering - 4.10.0-9 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild -- Add upstream patch to fix build on PPC64LE with GCC 15 - -* Mon Dec 23 2024 Orion Poplawski - 4.10.0-8 -- Rebuild with numpy 2.x (rhbz#2333781) +* Fri Mar 21 2025 Nicolas Chauvet - 4.10.0-8 +- Backport switch to qt6 for epel10 * Tue Nov 12 2024 Sandro Mani - 4.10.0-7 - Rebuild (tesseract) diff --git a/qt69.patch b/qt69.patch deleted file mode 100644 index fa59991..0000000 --- a/qt69.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- opencv-4.11.0/modules/highgui/CMakeLists.txt 2025-01-08 04:47:46.000000000 -0800 -+++ opencv-4.11.0/modules/highgui/CMakeLists.txt.new 2025-07-08 15:54:10.138078285 -0700 -@@ -125,7 +125,7 @@ - endif() - - foreach(dt_dep ${qt_deps}) -- add_definitions(${Qt${QT_VERSION_MAJOR}${dt_dep}_DEFINITIONS}) -+ link_libraries(${Qt${QT_VERSION_MAJOR}${dt_dep}}) - include_directories(${Qt${QT_VERSION_MAJOR}${dt_dep}_INCLUDE_DIRS}) - list(APPEND HIGHGUI_LIBRARIES ${Qt${QT_VERSION_MAJOR}${dt_dep}_LIBRARIES}) - endforeach() diff --git a/sources b/sources index 696874a..bd0466e 100644 --- a/sources +++ b/sources @@ -1,5 +1,6 @@ -SHA512 (opencv-clean-4.12.0.tar.gz) = 7bcbe3629dda78e63cd737568ed94ef3f63dd7b11196247ffd03f93fed5ae9a96483d9fae25385dfd6f30c8c2e11677fd9f5c26b2f7a1bd88ca303b06a98b87d -SHA512 (opencv_contrib-clean-4.12.0.tar.gz) = e279bd46d2b4a3e4d8c98401e2abdd873ee15b63d14d16b7c9980f84fee02c08491cab4d8cd6b4e493d0892e254e56dd759235f3606332a1b264a41be3c8f9d8 +SHA512 (opencv-clean-4.10.0.tar.gz) = 0fc8c4f870bcc67bd70bb1d438afe62a4e0874a9e6af364fd0cf08648c6110469fb7d433d561b12f3cae88bcc7b74d2680ffb0364a028a90918fb1d9542f544a SHA512 (wechat-20230712.git3487ef7.tar.gz) = bc4f220465de41df8af0cb35312c1db155976d05f13a60e43c1798b161d8f56388e34a59108fb3e27e8c97b53acfd198256d9ae420b5f70a32ddc1ea65c3c8a6 +SHA512 (opencv_contrib-clean-4.10.0.tar.gz) = 382a08b4c4be6ad2f2c0f682a169c119e6be4d04b57973fd85daf16cf0cd78dc55a64729c7efbd39b41711ef3dd354e7f323c384c5a5d39d8c1d9f42c9eedbe5 +SHA512 (opencv_extra-clean-4.10.0.tar.gz) = 8c61246ae773e50bb3080f732aaac8a1fb762e81a0f8abdf0987377a92d97ecfcbe99c3a1058ed313008c039b269e65646463f82b347e3a546f32dd4c8fed903 SHA512 (face_landmark_model.dat.xz) = 7558f29431bb9cad1f22ee067ad3ed41be8f68b865992eb7d3a5ce6b6b9e1d031cb03e33c3c149220ef8faebd0471703a8a3bbb06402bcc8ce76bd28317aa307 -SHA512 (962ce79e0b95591f226431f7b5f152cd-v0.1.2e.zip) = 87c65716498ca2e4f64fb9a1f78f7e5c48fffff5fc6735027edfb7d7ccc0d9f5b01c85f4b956ddc7e1c35c69ee2513d48a7da91764c2fd01d073ee5a1fc90c6f +SHA512 (dbb095a8bf3008e91edbbf45d8d34885-v0.1.2d.zip) = f6f87be8932c0c0ca40bec20b750ab3df27dac44f4507211c29c60f42160e3f2f2133b52c18245eff5241f216a3f5526d299937470b69b125e8eca369c8f6939