Compare commits

...
Sign in to create a new pull request.

55 commits

Author SHA1 Message Date
Nicolas Chauvet
ce6c184c9e Apply patch18 2025-12-10 15:13:37 +01:00
Nicolas Chauvet
781cdc0ccb Fix build with Eigen3 > 3 2025-12-10 15:13:00 +01:00
Nicolas Chauvet
7c6a57d532 Update to 4.12.0 2025-11-28 14:51:08 +01:00
Sandro Mani
e4430f2027 Rebuild (gdal) 2025-11-23 22:38:24 +01:00
Cristian Le
fb65d41d94 Allow to build with CMake 4.0 (rhbz#2381337) 2025-11-12 18:28:03 +01:00
Dominik 'Rathann' Mierzejewski
97b0aa4a26 Rebuilt for FFmpeg 8 2025-11-05 10:08:20 +01:00
Nicolas Chauvet
d3835e3b0b Merge #43 Fix importing of Python module 2025-10-31 19:08:57 +00:00
Federico Pellegrin
1aebdc2c48 Fix importing of Python module (#2406800) 2025-10-30 20:26:11 +01:00
Yaakov Selkowitz
e035a958ac Enable C++17 on RHEL 11
While this was originally intended for the future inclusion of Protobuf v4,
rawhide and ELN now include Eigen 5.0 which requires a newer C++ standard.
2025-10-29 17:53:07 -04:00
Nicolas Chauvet
6bc8b75d58 Drop eigen2 condition 2025-10-21 17:57:23 +02:00
Nicolas Chauvet
63f9fb5af3 Set without eigen off 2025-10-21 17:56:41 +02:00
Dominik 'Rathann' Mierzejewski
544ff83f8c fix build without eigen 2025-10-21 12:48:21 +02:00
Nicolas Chauvet
50e2f38acd Add changelog 2025-10-20 20:52:35 +02:00
Nicolas Chauvet
ef49f5c10a Workaround fix build for i686 with eigen 5
Disabling AVX for i686 fixes build with eigen-5.0.0

https://gitlab.com/libeigen/eigen/-/issues/2991
2025-10-20 20:51:38 +02:00
Nicolas Chauvet
c610b9652a Add flatbuffers 2025-10-20 20:50:26 +02:00
Iñaki Úcar
84191fa7b9 https://fedoraproject.org/wiki/Changes/FlexiBLAS_as_BLAS/LAPACK_manager 2025-10-20 17:00:57 +02:00
Dominik 'Rathann' Mierzejewski
81d1bbe53c Fixed build with FFmpeg 8 2025-10-20 16:29:01 +02:00
Miro Hrončok
9db5b7b826 Conversion to %pyproject macros followup 2025-10-20 15:22:00 +02:00
Nicolas Chauvet
6e87dd17af Reduce optimization on i686
This avoid the case where some AVX code is used while not been available
for x86_64 like with eigen3
2025-10-17 20:08:41 +02:00
Nicolas Chauvet
a3c6808be9 Revert disabling eigen3 on i686
This disable some modules, so fix it another way instead
2025-10-17 20:08:33 +02:00
Nicolas Chauvet
f5faab5a89 Hack for pyprojects with opencv 2025-10-17 11:45:12 +02:00
Nicolas Chauvet
f7ff54a581 Add missing br python3-pip 2025-10-17 11:45:12 +02:00
Nicolas Chauvet
566a1c2362 Fixup disable eigen3 on i686 2025-10-17 10:19:52 +02:00
Nicolas Chauvet
a4104bd492 Add missing pyproject_wheel 2025-10-16 19:41:03 +02:00
Nicolas Chauvet
b5b2dac5f4 Disable eigen3 on f44 i686 for now 2025-10-16 19:40:34 +02:00
Nicolas Chauvet
16a14b4b00 Enable IMGCODEC_GIF 2025-10-16 15:27:19 +02:00
Nicolas Chauvet
9b977f4e00 Add missing option 2025-10-16 15:27:17 +02:00
Nicolas Chauvet
a3caee55c6 Update changelog 2025-10-16 14:54:32 +02:00
Nicolas Chauvet
ddca32a934 Use pyprojectize - thanks Miro ! 2025-10-16 14:52:54 +02:00
Nicolas Chauvet
ec4ea19d19 Drop openni-primesense 2025-09-30 20:40:45 +02:00
Python Maint
896754e411 Rebuilt for Python 3.14.0rc3 bytecode 2025-09-19 12:34:33 +02:00
Orion Poplawski
7a756537a3 Rebuild for VTK 9.5 2025-08-24 08:02:13 -06:00
Jerry James
06d07a9e3b Rebuild for tbb 2022.2.0 2025-08-20 13:47:37 -06:00
Python Maint
fbe317b035 Rebuilt for Python 3.14.0rc2 bytecode 2025-08-15 13:03:59 +02:00
Adam Williamson
1477217e3d Rebuild for new gdal 2025-07-31 23:41:40 -07:00
Nicolas Chauvet
709fa3cec9 Update changelog 2025-07-29 10:27:41 +02:00
Nicolas Chauvet
974e024962 Add missing BR libavif 2025-07-29 10:24:17 +02:00
Nicolas Chauvet
56d06cb4b7 Drop undefine cmake in source build 2025-07-29 10:24:17 +02:00
Fedora Release Engineering
0e27e77c73 Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild 2025-07-24 23:34:35 +00:00
Adam Williamson
6086565bcb Correct qt patch application (d'oh) 2025-07-08 16:15:05 -07:00
Adam Williamson
f516d8688f Add patch from Atri Bhattacharya to fix build with Qt 6.9 2025-07-08 16:13:13 -07:00
Python Maint
a3627e6bbb Rebuilt for Python 3.14 2025-06-04 08:17:42 +02:00
Yaakov Selkowitz
12c310ffa4 Use Qt6 in highgui and cvv
Qt5 is deprecated, and kstars (the only package which uses both
opencv-highgui and Qt) is now using Qt6 in F42+.  Other dependents of
highgui are not using Qt directly otherwise, and cvv has no dependents.
2025-03-11 08:30:54 -04:00
Adam Williamson
9a00dd9072 Backport all post-4.11.0 PNG fixes, including big-endian fix
This backports all changes to the PNG reading code since 4.11.0,
mainly to get the fix for #2345306, PNG read fails on big-endian.
It's difficult to backport just that fix to 4.11.0 as it's built
on all the earlier changes, and the earlier changes look like
useful fixes too in any case.

See upstream https://github.com/opencv/opencv/issues/26913 and
https://github.com/opencv/opencv/pull/26915 .

Resolves: rhbz#2345306

Signed-off-by: Adam Williamson <awilliam@redhat.com>
2025-02-18 12:16:02 -08:00
Sérgio M. Basto
3219158b47 Add upstream patch to fix build on PPC64LE
https://github.com/opencv/opencv/pull/26750
core: fixed VSX intrinsics implementation
2025-02-03 00:45:54 +00:00
Packit
74ecc5eff2 Update to 4.11.0 upstream release
- Resolves: rhbz#2336422
2025-02-03 00:43:48 +00:00
Sérgio M. Basto
234dd7bc9f Rename condition va to libva because is not easy search by va only 2025-02-03 00:39:43 +00:00
Sérgio M. Basto
392683e0c6 Add upstream patch to fix build on PPC64LE with GCC 15 2025-01-18 00:19:28 +00:00
Fedora Release Engineering
687d848338 Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild 2025-01-17 21:38:40 +00:00
Sérgio M. Basto
08442e3b73 Rollback and use files_to_sync as packit team suggested 2025-01-09 14:39:59 +00:00
Sérgio M. Basto
7ac87dc3ab [packit] back to create-archive and in last step print the files generated 2025-01-09 13:16:25 +00:00
Sérgio M. Basto
30cfb1b655 [packit] try to use prepare-files instead 2025-01-09 01:01:38 +00:00
Sérgio M. Basto
6b02736ca1 [packit] use action create-archive instead pre-sync 2025-01-09 00:42:18 +00:00
Sérgio M. Basto
cdde9111a9 Try to fix packit automation 2025-01-09 00:10:16 +00:00
Orion Poplawski
0b8a44ecd0 Rebuild with numpy 2.x (rhbz#2333781) 2024-12-22 18:08:16 -07:00
21 changed files with 2177 additions and 38 deletions

1
.gitignore vendored
View file

@ -5,3 +5,4 @@ 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

View file

@ -1,17 +1,19 @@
# 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 "cd ${PACKIT_DOWNSTREAM_REPO}; sed '3d;$d' ./opencv-clean.sh | VERSION=${PACKIT_PROJECT_VERSION} bash"
- bash -c "${PACKIT_DOWNSTREAM_REPO}/opencv-clean.sh ${PACKIT_PROJECT_VERSION}"
files_to_sync:
- src:
- "opencv*clean-*.tar.gz"
dest: .
jobs:
- job: pull_from_upstream
trigger: release
dist_git_branches:
- fedora-rawhide

View file

@ -0,0 +1,155 @@
From c399203e9861bf3ff5b976cd597b9820eee5d93a Mon Sep 17 00:00:00 2001
From: Vincent Rabaud <vrabaud@google.com>
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<png_bytep>& 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<size_t>(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<png_bytep>& rows_dst, const std::vector<png_bytep>& 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

View file

@ -0,0 +1,37 @@
From b7b84ec6364809306776b48206ad36266274c297 Mon Sep 17 00:00:00 2001
From: Vincent Rabaud <vrabaud@google.com>
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

View file

@ -0,0 +1,654 @@
From c29de7cc4b89c80f7ee910f318dfc1bc462d576c Mon Sep 17 00:00:00 2001
From: Vincent Rabaud <vrabaud@google.com>
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<PngDecoder>();
@@ -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<unsigned char*> _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<uint32_t>(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<unsigned char*> _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<png_bytep>& rows_dst, const std::vector<png_bytep>& 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

View file

@ -0,0 +1,121 @@
From eba1a8955f9d7f8aa8c6b3ddee4565ee4185136c Mon Sep 17 00:00:00 2001
From: Vincent Rabaud <vrabaud@google.com>
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<size_t>(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<size_t>(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

View file

@ -0,0 +1,170 @@
From 49c3a5eca58276daca4207c38a1579080aade23e Mon Sep 17 00:00:00 2001
From: Suleyman TURKMEN <sturkmen@hotmail.com>
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<png_bytep>& 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<size_t>(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<int>& 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<in
png_save_uint_32(buf_acTL, num_frames - first);
png_save_uint_32(buf_acTL + 4, loops);
- write_to_io(header, 1, 8, m_f);
+ writeToStreamOrBuffer(header, 8, m_f);
writeChunk(m_f, "IHDR", buf_IHDR, 13);
diff --git a/modules/imgcodecs/src/grfmt_png.hpp b/modules/imgcodecs/src/grfmt_png.hpp
index 5dfc86efcc..6e1a06473d 100644
--- a/modules/imgcodecs/src/grfmt_png.hpp
+++ b/modules/imgcodecs/src/grfmt_png.hpp
@@ -137,7 +137,13 @@ private:
CV_NODISCARD_STD bool processing_start(void* frame_ptr, const Mat& img);
CV_NODISCARD_STD bool processing_finish();
void compose_frame(std::vector<png_bytep>& rows_dst, const std::vector<png_bytep>& 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

View file

@ -0,0 +1,133 @@
From 8131e27e824740afa447a129e72a2f6a3876cbc9 Mon Sep 17 00:00:00 2001
From: Suleyman TURKMEN <sturkmen@hotmail.com>
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<in
if (palsize > 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<int>(animation.bgcolor[0]) & 0xFF) << 24 |
- (static_cast<int>(animation.bgcolor[1]) & 0xFF) << 16 |
- (static_cast<int>(animation.bgcolor[2]) & 0xFF) << 8 |
- (static_cast<int>(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

View file

@ -0,0 +1,39 @@
From d6c4ac2e5e9cb7ea607ecb8e70884a3c5a06654c Mon Sep 17 00:00:00 2001
From: Suleyman TURKMEN <sturkmen@hotmail.com>
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

View file

@ -0,0 +1,90 @@
From 0d99c4283620671be3009ec00eb260e5a759cc39 Mon Sep 17 00:00:00 2001
From: Vincent Rabaud <vrabaud@google.com>
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<in
if ((animation.bgcolor != Scalar()) && coltype)
{
unsigned char bgvalue[6] = {};
- bgvalue[1] = animation.bgcolor[0];
+ bgvalue[1] = animation.bgcolor[2];
bgvalue[3] = animation.bgcolor[1];
- bgvalue[5] = animation.bgcolor[2];
+ bgvalue[5] = animation.bgcolor[0];
writeChunk(m_f, "bKGD", bgvalue, 6); //the bKGD chunk must precede the first IDAT chunk, and must follow the PLTE chunk.
}
--
2.48.1

View file

@ -0,0 +1,367 @@
From 8aa1086ab475ef0040d3865e49edd6feba4eb7d3 Mon Sep 17 00:00:00 2001
From: Suleyman TURKMEN <sturkmen@hotmail.com>
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<std::string> Decode;
+typedef perf::TestBaseWithParam<std::string> 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<uchar> 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<uchar> 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<uchar> buf;
+
+ TEST_CYCLE() imencode(GetParam(), src, buf);
+
+ std::cout << "Encoded buffer size: " << buf.size()
+ << " bytes, Compression ratio: " << std::fixed << std::setprecision(2)
+ << (static_cast<double>(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<Mat> 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<uchar> 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<double>(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<int> &params) {
- std::vector<Mat> img_vec(1, img);
- return writemulti(img_vec, params);
-}
-
bool AvifEncoder::writeanimation(const Animation& animation,
const std::vector<int> &params) {
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<int>& params) CV_OVERRIDE;
bool writeanimation(const Animation& animation, const std::vector<int>& 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<uchar>& buf )
return true;
}
+bool BaseImageEncoder::write(const Mat &img, const std::vector<int> &params) {
+ std::vector<Mat> img_vec(1, img);
+ return writemulti(img_vec, params);
+}
+
bool BaseImageEncoder::writemulti(const std::vector<Mat>& img_vec, const std::vector<int>& params)
{
if(img_vec.size() > 1)
@@ -157,6 +162,7 @@ bool BaseImageEncoder::writemulti(const std::vector<Mat>& img_vec, const std::ve
bool BaseImageEncoder::writeanimation(const Animation&, const std::vector<int>& )
{
+ 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<int>& params) = 0;
+ virtual bool write(const Mat& img, const std::vector<int>& 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<int> &params) {
- std::vector<Mat> img_vec(1, img);
- return writemulti(img_vec, params);
-}
-
bool GifEncoder::writeanimation(const Animation& animation, const std::vector<int>& 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<int>& params) CV_OVERRIDE;
bool writeanimation(const Animation& animation, const std::vector<int>& 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<int>& 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::vector<in
}
}
- CV_UNUSED(isBilevel);
+ if (isBilevel)
+ CV_LOG_WARNING(NULL, "IMWRITE_PNG_BILEVEL parameter is not supported yet.");
uint32_t first =0;
uint32_t loops= animation.loop_count;
uint32_t coltype= animation.frames[0].channels() == 1 ? PNG_COLOR_TYPE_GRAY : animation.frames[0].channels() == 3 ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
diff --git a/modules/imgcodecs/src/loadsave.cpp b/modules/imgcodecs/src/loadsave.cpp
index ec25f8c610..37b0701c8a 100644
--- a/modules/imgcodecs/src/loadsave.cpp
+++ b/modules/imgcodecs/src/loadsave.cpp
@@ -1372,7 +1372,7 @@ bool imencode( const String& ext, InputArray _img,
else
code = encoder->writemulti(write_vec, params);
- encoder->throwOnEror();
+ encoder->throwOnError();
CV_Assert( code );
}
catch (const cv::Exception& e)
--
2.48.1

View file

@ -0,0 +1,54 @@
From ab0a4167057dadcfc497f0d4d653b5eec7fd586a Mon Sep 17 00:00:00 2001
From: Maksim Shabunin <maksim.shabunin@gmail.com>
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<size_t>(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

54
26750.patch Normal file
View file

@ -0,0 +1,54 @@
From 97f3f390661f2fd1168336820b89eb4383ce8528 Mon Sep 17 00:00:00 2001
From: Maksim Shabunin <maksim.shabunin@gmail.com>
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<typename _Tpvec0> 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)
{

35
26786.patch Normal file
View file

@ -0,0 +1,35 @@
From 63ef786a3a0afcd44bf842f967656052d52dde09 Mon Sep 17 00:00:00 2001
From: Maksim Shabunin <maksim.shabunin@gmail.com>
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

57
27536.patch Normal file
View file

@ -0,0 +1,57 @@
From 353b4ddf52db48ba85d2efaa33310afa0eb73a72 Mon Sep 17 00:00:00 2001
From: Kumataro <Kumataro@users.noreply.github.com>
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 <Kumataro@users.noreply.github.com>
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})

43
27691.patch Normal file
View file

@ -0,0 +1,43 @@
From 90c444abd387ffa70b2e72a34922903a2f0f4f5a Mon Sep 17 00:00:00 2001
From: Alexander Smorkalov <alexander.smorkalov@opencv.ai>
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));

View file

@ -1,3 +1,3 @@
This repository is maintained by packit.
https://packit.dev/
The file was generated using packit 0.97.1.post1.dev6+gc8c0314a.
The file was generated using packit 0.106.0.post1.dev8+g521f1e1d.

View file

@ -1,6 +1,6 @@
#!/bin/bash
VERSION=4.9.0
VERSION=$1
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/.*\///')

View file

@ -1,5 +1,3 @@
%undefine __cmake_in_source_build
%bcond_with tests
%bcond_without compat_openvc_pc
%if %{without tests}
@ -11,7 +9,6 @@
%bcond_with linters
%bcond_without ffmpeg
%bcond_without gstreamer
%bcond_with eigen2
%bcond_without eigen3
%bcond_without opencl
%ifarch x86_64 %{arm}
@ -25,9 +22,10 @@
%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
# check OpenCVFindLAPACK.cmake
# Now FlexiBLAS should be used instead: https://fedoraproject.org/wiki/Changes/FlexiBLAS_as_BLAS/LAPACK_manager
%bcond_with atlas
%bcond_without openblas
%bcond_with openblas
%bcond_without flexiblas
%bcond_without gdcm
%if 0%{?rhel} >= 8
%bcond_with vtk
@ -57,7 +55,7 @@
%bcond_with openexr
%endif
%bcond_without va
%bcond_without libva
%bcond_without vulkan
%define _lto_cflags %{nil}
@ -71,13 +69,13 @@
%endif
Name: opencv
Version: 4.10.0
Version: 4.12.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: 7%{?dist}
Release: 20%{?dist}
Summary: Collection of algorithms for computer vision
# This is normal three clause BSD.
License: BSD-3-Clause AND Apache-2.0 AND ISC
@ -95,7 +93,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: dbb095a8bf3008e91edbbf45d8d34885-v0.1.2d.zip
Source4: 962ce79e0b95591f226431f7b5f152cd-v0.1.2e.zip
Source5: xorg.conf
%global wechat_commit 3487ef7cde71d93c6a01bb0b84aa0f22c6128f6b
%global wechat_shortcommit %(c=%{wechat_commit}; echo ${c:0:7})
@ -104,6 +102,14 @@ 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
@ -115,7 +121,6 @@ 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
@ -126,6 +131,7 @@ BuildRequires: libdc1394-devel
%endif
%endif
BuildRequires: jasper-devel
BuildRequires: pkgconfig(libavif)
BuildRequires: libjpeg-devel
BuildRequires: libpng-devel
BuildRequires: libtiff-devel
@ -136,7 +142,7 @@ BuildRequires: OpenEXR-devel
}
%{?with_openni:
BuildRequires: openni-devel
%if 0%{?fedora}
%if 0%{?fedora} && 0%{?fedora} < 44
BuildRequires: openni-primesense
%endif
}
@ -147,7 +153,6 @@ BuildRequires: zlib-devel
BuildRequires: pkgconfig
BuildRequires: python3-devel
BuildRequires: python3-numpy
BuildRequires: python3-setuptools
%{?with_linters:
BuildRequires: pylint
BuildRequires: python3-flake8
@ -178,7 +183,8 @@ BuildRequires: python3-beautifulsoup4
#for doc/doxygen/bib2xhtml.pl
#BuildRequires: perl-open
BuildRequires: gflags-devel
BuildRequires: qt5-qtbase-devel
BuildRequires: qt6-qtbase-devel
BuildRequires: qt6-qt5compat-devel
BuildRequires: libGL-devel
BuildRequires: libGLU-devel
BuildRequires: hdf5-devel
@ -193,7 +199,6 @@ BuildRequires: harfbuzz-devel
BuildRequires: vtk-java
}
}
%{?with_atlas:BuildRequires: atlas-devel}
#ceres-solver-devel push eigen3-devel and tbb-devel
%{?with_tbb:
%{?with_eigen3:
@ -202,21 +207,22 @@ BuildRequires: vtk-java
# BuildRequires: ceres-solver-devel
}
}
%{?with_openblas:
BuildRequires: openblas-devel
BuildRequires: blas-devel
BuildRequires: lapack-devel
}
%{?with_atlas:BuildRequires: atlas-devel}
%{?with_openblas:BuildRequires: openblas-devel}
%{?with_flexiblas:BuildRequires: flexiblas-devel}
%{?with_gdcm:BuildRequires: gdcm-devel}
%{?with_libmfx:BuildRequires: libvpl-devel}
%{?with_clp:BuildRequires: coin-or-Clp-devel}
%{?with_va:BuildRequires: libva-devel}
%{?with_libva:BuildRequires: libva-devel}
%{?with_java:
BuildRequires: ant
BuildRequires: java-devel
}
%{?with_vulkan:BuildRequires: vulkan-headers}
#BuildRequires: flatbuffers-devel
%ifnarch i686
BuildRequires: flatbuffers-devel
BuildRequires: flatbuffers-compiler
%endif
%if %{with tests}
BuildRequires: xorg-x11-drv-dummy
BuildRequires: mesa-dri-drivers
@ -283,7 +289,9 @@ 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}
@ -403,6 +411,9 @@ 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
@ -425,14 +436,20 @@ 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
%if 0%{?fedora} > 38 || 0%{?rhel} > 10
-DCMAKE_CXX_STANDARD=17 \
%endif
-DCV_TRACE=OFF \
@ -451,6 +468,9 @@ install -pm 0644 %{S:4} .cache/ade/
-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 \
@ -475,7 +495,6 @@ install -pm 0644 %{S:4} .cache/ade/
-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 \
@ -491,20 +510,35 @@ install -pm 0644 %{S:4} .cache/ade/
-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_va: -DWITH_VA=ON } \
%{?with_libva: -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/
%py3_install -- --install-lib %{python3_sitearch}
%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
rm -rf %{buildroot}%{_datadir}/OpenCV/licenses/
%if %{with java}
@ -519,6 +553,14 @@ 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}
@ -529,7 +571,6 @@ ln -s -r %{buildroot}%{_jnidir}/opencv-%{javaver}.jar %{buildroot}%{_jnidir}/ope
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
@ -565,9 +606,14 @@ ln -s -r %{buildroot}%{_jnidir}/opencv-%{javaver}.jar %{buildroot}%{_jnidir}/ope
%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
%{python3_sitearch}/opencv-*.egg-info
%endif
%if %{with java}
%files java
@ -579,6 +625,77 @@ ln -s -r %{buildroot}%{_jnidir}/opencv-%{javaver}.jar %{buildroot}%{_jnidir}/ope
%changelog
* Sun Nov 23 2025 Sandro Mani <manisandro@gmail.com> - 4.11.0-20
- Rebuild (gdal)
* Tue Nov 11 2025 Cristian Le <git@lecris.dev> - 4.11.0-19
- Allow to build with CMake 4.0 (rhbz#2381337)
* Wed Nov 05 2025 Dominik Mierzejewski <dominik@greysector.net> - 4.11.0-18
- Rebuilt for FFmpeg 8
* Wed Oct 29 2025 Federico Pellegrin <fede@evolware.org> - 4.11.0-17
- Fix importing of Python module (#2406800)
* Mon Oct 20 2025 Nicolas Chauvet <kwizart@gmail.com> - 4.11.0-16
- Fix build with i686
* Mon Oct 20 2025 Iñaki Úcar <iucar@fedoraproject.org> - 4.11.0-15
- https://fedoraproject.org/wiki/Changes/FlexiBLAS_as_BLAS/LAPACK_manager
* Fri Oct 17 2025 Dominik Mierzejewski <dominik@greysector.net> - 4.11.0-14
- Fix build with FFmpeg 8
* Thu Oct 16 2025 Nicolas Chauvet <kwizart@gmail.com> - 4.11.0-13
- Use pyprojectize - thanks Miro !
* Tue Sep 30 2025 Nicolas Chauvet <kwizart@gmail.com> - 4.11.0-12
- Drop retired openni-primesense in fedora >= 44
* Fri Sep 19 2025 Python Maint <python-maint@redhat.com> - 4.11.0-11
- Rebuilt for Python 3.14.0rc3 bytecode
* Sun Aug 24 2025 Orion Poplawski <orion@nwra.com> - 4.11.0-10
- Rebuild for VTK 9.5
* Wed Aug 20 2025 Jerry James <loganjerry@gmail.com> - 4.11.0-9
- Rebuild for tbb 2022.2.0
* Fri Aug 15 2025 Python Maint <python-maint@redhat.com> - 4.11.0-8
- Rebuilt for Python 3.14.0rc2 bytecode
* Thu Jul 31 2025 Adam Williamson <awilliam@redhat.com> - 4.11.0-7
- Rebuild for new gdal
* Tue Jul 29 2025 Nicolas Chauvet <kwizart@gmail.com> - 4.11.0-6
- Add missing BR libavif
* Thu Jul 24 2025 Fedora Release Engineering <releng@fedoraproject.org> - 4.11.0-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
* Tue Jul 08 2025 Adam Williamson <awilliam@redhat.com> - 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 <yselkowi@redhat.com> - 4.11.0-3
- Use Qt6 in highgui and cvv
* Tue Feb 18 2025 Adam Williamson <awilliam@redhat.com> - 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 <sergio@serjux.com> 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 <releng@fedoraproject.org> - 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 <orion@nwra.com> - 4.10.0-8
- Rebuild with numpy 2.x (rhbz#2333781)
* Tue Nov 12 2024 Sandro Mani <manisandro@gmail.com> - 4.10.0-7
- Rebuild (tesseract)

11
qt69.patch Normal file
View file

@ -0,0 +1,11 @@
--- 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()

View file

@ -1,6 +1,5 @@
SHA512 (opencv-clean-4.10.0.tar.gz) = 0fc8c4f870bcc67bd70bb1d438afe62a4e0874a9e6af364fd0cf08648c6110469fb7d433d561b12f3cae88bcc7b74d2680ffb0364a028a90918fb1d9542f544a
SHA512 (opencv-clean-4.12.0.tar.gz) = 7bcbe3629dda78e63cd737568ed94ef3f63dd7b11196247ffd03f93fed5ae9a96483d9fae25385dfd6f30c8c2e11677fd9f5c26b2f7a1bd88ca303b06a98b87d
SHA512 (opencv_contrib-clean-4.12.0.tar.gz) = e279bd46d2b4a3e4d8c98401e2abdd873ee15b63d14d16b7c9980f84fee02c08491cab4d8cd6b4e493d0892e254e56dd759235f3606332a1b264a41be3c8f9d8
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 (dbb095a8bf3008e91edbbf45d8d34885-v0.1.2d.zip) = f6f87be8932c0c0ca40bec20b750ab3df27dac44f4507211c29c60f42160e3f2f2133b52c18245eff5241f216a3f5526d299937470b69b125e8eca369c8f6939
SHA512 (962ce79e0b95591f226431f7b5f152cd-v0.1.2e.zip) = 87c65716498ca2e4f64fb9a1f78f7e5c48fffff5fc6735027edfb7d7ccc0d9f5b01c85f4b956ddc7e1c35c69ee2513d48a7da91764c2fd01d073ee5a1fc90c6f