Compare commits

..

2 commits

Author SHA1 Message Date
Nicolas Chauvet
a5ff02ed97 Fixup patch macro 2025-07-29 12:24:20 +02:00
Nicolas Chauvet
a6e60893e4 Rebuilt for gdal - rhbz#2383114 2025-07-29 12:17:54 +02:00
22 changed files with 166 additions and 2515 deletions

4
.gitignore vendored
View file

@ -2,7 +2,3 @@ OpenCV*.tar.*
opencv*.tar.*
face_landmark_model.dat.xz
/b624b995ec9c439cbc2e9e6ee940d3a2-v0.1.1f.zip
/fa4b3e25167319cb0fa9432ef8281945-v0.1.2a.zip
/wechat-20230712.git3487ef7.tar.gz
/dbb095a8bf3008e91edbbf45d8d34885-v0.1.2d.zip
/962ce79e0b95591f226431f7b5f152cd-v0.1.2e.zip

View file

@ -1,19 +0,0 @@
# See the documentation for more information:
# https://packit.dev/docs/configuration/
# run opencv-clean.sh
# the sed currently hacks the script so that the version is correctly set and the sources upload is handled by Packit
actions:
pre-sync:
- bash -c "${PACKIT_DOWNSTREAM_REPO}/opencv-clean.sh ${PACKIT_PROJECT_VERSION}"
files_to_sync:
- src:
- "opencv*clean-*.tar.gz"
dest: .
jobs:
- job: pull_from_upstream
trigger: release
dist_git_branches:
- fedora-rawhide

View file

@ -1,155 +0,0 @@
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

@ -1,37 +0,0 @@
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

@ -1,654 +0,0 @@
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

@ -1,121 +0,0 @@
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

@ -1,170 +0,0 @@
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

@ -1,133 +0,0 @@
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

@ -1,39 +0,0 @@
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

@ -1,90 +0,0 @@
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

@ -1,367 +0,0 @@
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

@ -1,54 +0,0 @@
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

View file

@ -1,54 +0,0 @@
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)
{

View file

@ -1,35 +0,0 @@
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

View file

@ -1,57 +0,0 @@
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})

View file

@ -1,43 +0,0 @@
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 +0,0 @@
This repository is maintained by packit.
https://packit.dev/
The file was generated using packit 0.106.0.post1.dev8+g521f1e1d.

View file

@ -0,0 +1,24 @@
diff -up opencv-4.1.2/cmake/templates/OpenCVConfig.cmake.in.orig opencv-4.1.2/cmake/templates/OpenCVConfig.cmake.in
--- opencv-4.1.2/cmake/templates/OpenCVConfig.cmake.in.orig 2019-10-10 00:53:14.000000000 +0200
+++ opencv-4.1.2/cmake/templates/OpenCVConfig.cmake.in 2019-10-17 11:08:46.626400320 +0200
@@ -106,7 +106,7 @@ set(OpenCV_SHARED @BUILD_SHARED_LIBS@)
set(OpenCV_USE_MANGLED_PATHS @OpenCV_USE_MANGLED_PATHS_CONFIGCMAKE@)
set(OpenCV_LIB_COMPONENTS @OPENCV_MODULES_CONFIGCMAKE@)
-set(__OpenCV_INCLUDE_DIRS @OpenCV_INCLUDE_DIRS_CONFIGCMAKE@)
+set(__OpenCV_INCLUDE_DIRS @OpenCV_INCLUDE_DIRS_CONFIGCMAKE@ @OpenCV_INCLUDE_DIRS_CONFIGCMAKE@/opencv2)
set(OpenCV_INCLUDE_DIRS "")
foreach(d ${__OpenCV_INCLUDE_DIRS})
diff -up opencv-4.1.2/cmake/templates/opencv-XXX.pc.in.orig opencv-4.1.2/cmake/templates/opencv-XXX.pc.in
--- opencv-4.1.2/cmake/templates/opencv-XXX.pc.in.orig 2019-10-10 00:53:14.000000000 +0200
+++ opencv-4.1.2/cmake/templates/opencv-XXX.pc.in 2019-10-17 11:04:11.486014573 +0200
@@ -3,7 +3,7 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
-includedir_old=@includedir@/opencv
+includedir_old=@includedir@/opencv2
includedir_new=@includedir@
Name: OpenCV

View file

@ -1,6 +1,6 @@
#!/bin/bash
VERSION=$1
VERSION=4.6.0
wget -c https://github.com/opencv/opencv/archive/${VERSION}/opencv-${VERSION}.tar.gz
wget -c https://github.com/opencv/opencv_contrib/archive/${VERSION}/opencv_contrib-${VERSION}.tar.gz
@ -31,4 +31,4 @@ tar zcf opencv_extra-clean-${VERSION}.tar.gz opencv_extra-${VERSION}/
rm -r opencv_extra-${VERSION}/
#echo fedpkg new-sources $(spectool -l --sources opencv.spec | sed 's/.*: //;s/.*\///')
echo fedpkg new-sources $(spectool -l --sources opencv.spec)

View file

@ -1,31 +1,31 @@
%bcond_with tests
%bcond_without compat_openvc_pc
%if %{without tests}
%bcond_with extras_tests
%else
%bcond_without extras_tests
%endif
%undefine __cmake_in_source_build
%bcond_without tests
%bcond_without extras
# linters are enabled by default if BUILD_DOCS OR BUILD_EXAMPLES
%bcond_with linters
%bcond_without ffmpeg
%bcond_without linters
%bcond_with ffmpeg
%bcond_without gstreamer
%bcond_with eigen2
%bcond_without eigen3
%bcond_without opencl
%ifarch x86_64 %{arm}
%if 0%{?rhel} >= 8
%bcond_with openni
%else
%ifarch %{ix86} x86_64 %{arm}
%bcond_without openni
%else
# we dont have openni in other archs
%bcond_with openni
%endif
%endif
%bcond_without tbb
%bcond_with cuda
%bcond_without xine
%bcond_with xine
# Atlas need (missing: Atlas_CLAPACK_INCLUDE_DIR Atlas_CBLAS_LIBRARY Atlas_BLAS_LIBRARY Atlas_LAPACK_LIBRARY)
# LAPACK may use atlas or openblas since now it detect openblas, atlas is not used anyway, more info please
# Now FlexiBLAS should be used instead: https://fedoraproject.org/wiki/Changes/FlexiBLAS_as_BLAS/LAPACK_manager
# check OpenCVFindLAPACK.cmake
%bcond_with atlas
%bcond_with openblas
%bcond_without flexiblas
%bcond_without openblas
%bcond_without gdcm
%if 0%{?rhel} >= 8
%bcond_with vtk
@ -35,6 +35,7 @@
%ifarch x86_64
%bcond_without libmfx
%bcond_without va
%else
%bcond_with libmfx
%endif
@ -49,13 +50,6 @@
%bcond_with java
%endif
%if 0%{?fedora}
%bcond_without openexr
%else
%bcond_with openexr
%endif
%bcond_without libva
%bcond_without vulkan
%define _lto_cflags %{nil}
@ -69,16 +63,16 @@
%endif
Name: opencv
Version: 4.12.0
Version: 4.6.0
%global javaver %(foo=%{version}; echo ${foo//./})
%global majorver %(foo=%{version}; a=(${foo//./ }); echo ${a[0]} )
%global minorver %(foo=%{version}; a=(${foo//./ }); echo ${a[1]} )
%global padding %(digits=00; num=%{minorver}; echo ${digits:${#num}:${#digits}} )
%global abiver %(echo %{majorver}%{padding}%{minorver} )
Release: 20%{?dist}
Release: 8%{?dist}
Summary: Collection of algorithms for computer vision
# This is normal three clause BSD.
License: BSD-3-Clause AND Apache-2.0 AND ISC
License: BSD
URL: https://opencv.org
# TO PREPARE TARBALLS FOR FEDORA
# Edit opencv-clean.sh and set VERSION, save file and run opencv-clean.sh
@ -88,28 +82,16 @@ URL: https://opencv.org
#
Source0: %{name}-clean-%{version}.tar.gz
Source1: %{name}_contrib-clean-%{version}.tar.gz
%{?with_extras_tests:
#Source2: %{name}_extra-clean-%{version}.tar.gz
%{?with_extras:
Source2: %{name}_extra-clean-%{version}.tar.gz
}
Source3: face_landmark_model.dat.xz
# SRC=v0.1.2d.zip ; wget https://github.com/opencv/ade/archive/$SRC; mv $SRC $(md5sum $SRC | cut -d' ' -f1)-$SRC
Source4: 962ce79e0b95591f226431f7b5f152cd-v0.1.2e.zip
# from https://github.com/opencv/ade/archive/v0.1.1f.zip
Source4: b624b995ec9c439cbc2e9e6ee940d3a2-v0.1.1f.zip
Source5: xorg.conf
%global wechat_commit 3487ef7cde71d93c6a01bb0b84aa0f22c6128f6b
%global wechat_shortcommit %(c=%{wechat_commit}; echo ${c:0:7})
%global wechat_gitdate 20230712
Source6: https://github.com/WeChatCV/opencv_3rdparty/archive/%{wechat_commit}/wechat-%{wechat_gitdate}.git%{wechat_shortcommit}.tar.gz
Patch0: opencv-4.1.0-install_3rdparty_licenses.patch
Patch3: opencv.python.patch
# Fix build with Qt 6.9, by Atri Bhattacharya (thanks)
# https://github.com/opencv/opencv/issues/27223#issuecomment-2797750952
Patch16: qt69.patch
# Fix build with FFmpeg 8
Patch17: https://github.com/opencv/opencv/pull/27691.patch
# Fix detect Eigen3 > 3
Patch18: https://github.com/opencv/opencv/pull/27536.patch
BuildRequires: gcc-c++
BuildRequires: cmake >= 2.6.3
@ -121,6 +103,7 @@ BuildRequires: pkgconfig(cufft-%{?_cuda_version})
BuildRequires: pkgconfig(nppc-%{?_cuda_version})
%{?with_dnn_cuda:BuildRequires: libcudnn8-devel}
}
%{?with_eigen2:BuildRequires: eigen2-devel}
%{?with_eigen3:BuildRequires: eigen3-devel}
BuildRequires: libtheora-devel
BuildRequires: libvorbis-devel
@ -131,20 +114,15 @@ BuildRequires: libdc1394-devel
%endif
%endif
BuildRequires: jasper-devel
BuildRequires: pkgconfig(libavif)
BuildRequires: libjpeg-devel
BuildRequires: libpng-devel
BuildRequires: libtiff-devel
BuildRequires: libGL-devel
BuildRequires: libv4l-devel
%{?with_openexr:
BuildRequires: OpenEXR-devel
}
%{?with_openni:
BuildRequires: openni-devel
%if 0%{?fedora} && 0%{?fedora} < 44
BuildRequires: openni-primesense
%endif
}
%{?with_tbb:
BuildRequires: tbb-devel
@ -158,13 +136,7 @@ BuildRequires: pylint
BuildRequires: python3-flake8
}
BuildRequires: swig >= 1.3.24
%{?with_ffmpeg:
BuildRequires: pkgconfig(libavcodec)
BuildRequires: pkgconfig(libavformat)
BuildRequires: pkgconfig(libavutil)
BuildRequires: pkgconfig(libswscale)
BuildRequires: pkgconfig(libavdevice)
}
%{?with_ffmpeg:BuildRequires: ffmpeg-devel >= 0.4.9}
%if 0%{?fedora} || 0%{?rhel} > 7
%{?with_gstreamer:BuildRequires: gstreamer1-devel gstreamer1-plugins-base-devel}
%else
@ -183,15 +155,14 @@ BuildRequires: python3-beautifulsoup4
#for doc/doxygen/bib2xhtml.pl
#BuildRequires: perl-open
BuildRequires: gflags-devel
BuildRequires: qt6-qtbase-devel
BuildRequires: qt6-qt5compat-devel
BuildRequires: qt5-qtbase-devel
BuildRequires: libGL-devel
BuildRequires: libGLU-devel
BuildRequires: hdf5-devel
BuildRequires: openjpeg2-devel
BuildRequires: freetype-devel
BuildRequires: harfbuzz-devel
# Module opencv_ovis disabled because of incompatible OGRE3D version < 1.11.5
# Module opencv_ovis disabled because of incompatible OGRE3D version < 1.10
# BuildRequires: ogre-devel
%{?with_vtk:BuildRequires: vtk-devel}
%{?with_vtk:
@ -199,6 +170,7 @@ BuildRequires: harfbuzz-devel
BuildRequires: vtk-java
}
}
%{?with_atlas:BuildRequires: atlas-devel}
#ceres-solver-devel push eigen3-devel and tbb-devel
%{?with_tbb:
%{?with_eigen3:
@ -207,29 +179,26 @@ BuildRequires: vtk-java
# BuildRequires: ceres-solver-devel
}
}
%{?with_atlas:BuildRequires: atlas-devel}
%{?with_openblas:BuildRequires: openblas-devel}
%{?with_flexiblas:BuildRequires: flexiblas-devel}
%{?with_openblas:
BuildRequires: openblas-devel
BuildRequires: blas-devel
BuildRequires: lapack-devel
}
%{?with_gdcm:BuildRequires: gdcm-devel}
%{?with_libmfx:BuildRequires: libvpl-devel}
%{?with_libmfx:BuildRequires: libmfx-devel}
%{?with_clp:BuildRequires: coin-or-Clp-devel}
%{?with_libva:BuildRequires: libva-devel}
%{?with_va:BuildRequires: libva-devel}
%{?with_java:
BuildRequires: ant
BuildRequires: java-devel
}
%{?with_vulkan:BuildRequires: vulkan-headers}
%ifnarch i686
BuildRequires: flatbuffers-devel
BuildRequires: flatbuffers-compiler
%endif
%if %{with tests}
BuildRequires: xorg-x11-drv-dummy
BuildRequires: mesa-dri-drivers
%endif
Requires: opencv-core%{_isa} = %{version}-%{release}
Requires: opencv-data = %{version}-%{release}
%description
OpenCV means Intel® Open Source Computer Vision Library. It is a collection of
@ -240,122 +209,16 @@ and Computer Vision algorithms.
%package core
Summary: OpenCV core libraries
Provides: bundled(quirc) = 1.0
Obsoletes: python2-%{name} < %{version}
# any removed modules should be listed here
Obsoletes: %{name}-core < 4.8.0-2
Obsoletes: %{name}-contrib < 4.8.0-2
Obsoletes: python2-%{name} < %{version}-%{release}
%description core
This package contains the OpenCV C/C++ core libraries.
%package data
Summary: OpenCV data
BuildArch: noarch
%description data
This package contains OpenCV data.
%global opencv_devel_requires %{name}-core%{_isa} = %{version}-%{release}
%define opencv_module_subpkg(m:d:) \
%global opencv_devel_requires %{opencv_devel_requires} %{name}-%{-m*}%{_isa} = %{version}-%{release}\
%define modulename %{-m:%{-m*}}%{!-m:%{error:Module name not defined}}\
%define moduledesc %{-d:%{-d*}}%{!-d:%{-m*}}\
%package %{modulename}\
Summary: OpenCV module: %{moduledesc}\
Requires: %{name}-core%{_isa} = %{version}-%{release}\
\
%description %{modulename}\
This package contains the OpenCV %{moduledesc} module runtime.\
\
%files %{modulename}\
%{_libdir}/libopencv_%{modulename}.so.{%{abiver},%{version}}
# main modules
%opencv_module_subpkg -m calib3d -d %{quote:Camera Calibration and 3D Reconstruction}
%opencv_module_subpkg -m dnn -d %{quote:Deep Neural Network}
%opencv_module_subpkg -m features2d -d %{quote:2D Feature Detection}
%opencv_module_subpkg -m flann -d %{quote:Clustering and Search in Multi-dimensional Space}
%opencv_module_subpkg -m gapi -d %{quote:Graph API}
%opencv_module_subpkg -m highgui -d %{quote:High-level GUI}
%opencv_module_subpkg -m imgcodecs -d %{quote:Image Encoding/Decoding}
%opencv_module_subpkg -m imgproc -d %{quote:Image Processing}
%opencv_module_subpkg -m ml -d %{quote:Machine Learning}
%opencv_module_subpkg -m objdetect -d %{quote:Object Detection}
%opencv_module_subpkg -m photo -d %{quote:Computational Photography}
%opencv_module_subpkg -m stitching -d %{quote:Images stitching}
%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}
%opencv_module_subpkg -m ccalib -d %{quote:Custom Calibration Pattern}
%if %{with cuda}
%opencv_module_subpkg -m cudaarithm -d %{quote:CUDA Matrix Arithmatic}
%opencv_module_subpkg -m cudabgsegm -d %{quote:CUDA Background Segmentation}
%opencv_module_subpkg -m cudacodec -d %{quote:CUDA Video Encoding/Decoding}
%opencv_module_subpkg -m cudafeatures2d -d %{quote:CUDA 2D Feature Detection}
%opencv_module_subpkg -m cudafilters -d %{quote:CUDA Image Filtering}
%opencv_module_subpkg -m cudaimgproc -d %{quote:CUDA Image Processing}
%opencv_module_subpkg -m cudalegacy -d %{quote:CUDA Legacy Support}
%opencv_module_subpkg -m cudaobjdetect -d %{quote:CUDA Object Detection}
%opencv_module_subpkg -m cudaoptflow -d %{quote:CUDA Optical Flow}
%opencv_module_subpkg -m cudastereo -d %{quote:CUDA Stereo Correspondance}
%opencv_module_subpkg -m cudawarping -d %{quote:CUDA Image Warping}
%opencv_module_subpkg -m cudev -d %{quote:CUDA Device Layer}
%endif
%opencv_module_subpkg -m cvv -d %{quote:Interactive Computer Vision Visual Debugging}
%opencv_module_subpkg -m datasets -d %{quote:Datasets Framework}
%opencv_module_subpkg -m dnn_objdetect -d %{quote:Deep Neural Network Object Detection}
%opencv_module_subpkg -m dnn_superres -d %{quote:Deep Neural Network Super Resolution}
%opencv_module_subpkg -m dpm -d %{quote:Deformable Part-based Models}
%opencv_module_subpkg -m face -d %{quote:Face Analysis}
%opencv_module_subpkg -m freetype -d %{quote:Freetype/Harfbuzz UTF-8 Strings}
%opencv_module_subpkg -m fuzzy -d %{quote:Fuzzy Math-based Image Processing}
%opencv_module_subpkg -m hdf -d %{quote:HDF Data Format I/O}
%opencv_module_subpkg -m hfs -d %{quote:Heirarchical Feature Selection}
%opencv_module_subpkg -m img_hash -d %{quote:Image Hashing}
%opencv_module_subpkg -m intensity_transform -d %{quote:Intensity Transformation}
%opencv_module_subpkg -m line_descriptor -d %{quote:Extracted Line Binary Descriptor}
%opencv_module_subpkg -m mcc -d %{quote:Macbeth Chart}
%opencv_module_subpkg -m optflow -d %{quote:Optical Flow Algorithms}
#opencv_module_subpkg -m ovis -d %%{quote:OGRE 3D Visualiser}
%opencv_module_subpkg -m phase_unwrapping -d %{quote:Phase Unwrapping}
%opencv_module_subpkg -m plot -d %{quote:2D Plotting}
%opencv_module_subpkg -m quality -d %{quote:Image Quality Analysis}
%opencv_module_subpkg -m rapid -d %{quote:Silhouette based 3D Object Tracking}
%opencv_module_subpkg -m reg -d %{quote:Image Registration}
%opencv_module_subpkg -m rgbd -d %{quote:RGB-Depth Processing}
%opencv_module_subpkg -m saliency -d %{quote:Saliency}
%opencv_module_subpkg -m shape -d %{quote:Shape Distance and Matching}
%opencv_module_subpkg -m signal -d %{quote:Signal processing algorithms}
%opencv_module_subpkg -m stereo -d %{quote:Stereo Correspondance}
%opencv_module_subpkg -m structured_light -d %{quote:Structed Light}
%opencv_module_subpkg -m superres -d %{quote:Super Resolution}
%opencv_module_subpkg -m surface_matching -d %{quote:Surface Matching}
%opencv_module_subpkg -m text -d %{quote:Text Detection and Recognition}
%opencv_module_subpkg -m tracking -d %{quote:Tracking}
%opencv_module_subpkg -m videostab -d %{quote:Video Stabilization}
%if %{with vtk}
%opencv_module_subpkg -m viz -d %{quote:3D Visualizer}
%endif
%opencv_module_subpkg -m wechat_qrcode -d %{quote:WeChat QR code detector}
%opencv_module_subpkg -m ximgproc -d %{quote:Extended Image Processing}
%opencv_module_subpkg -m xobjdetect -d %{quote:Extended Object Detection}
%opencv_module_subpkg -m xphoto -d %{quote:Extended Photo Processing}
%package devel
Summary: Development files for using the OpenCV library
Requires: %{name}%{_isa} = %{version}-%{release}
Requires: %{name}-data = %{version}-%{release}
Requires: %{opencv_devel_requires}
Requires: %{name}-contrib%{_isa} = %{version}-%{release}
%description devel
This package contains the OpenCV C/C++ library and header files, as well as
@ -396,24 +259,30 @@ Requires: %{name}-core%{_isa} = %{version}-%{release}
This package contains Java bindings for the OpenCV library.
%prep
# autosetup doesn't work with 2 sources
# https://github.com/rpm-software-management/rpm/issues/1204
%setup -q -a1 %{?with_extras_tests:-a2} -a6
%package contrib
Summary: OpenCV contributed functionality
%description contrib
This package is intended for development of so-called "extra" modules, contributed
functionality. New modules quite often do not have stable API, and they are not
well-tested. Thus, they shouldn't be released as a part of official OpenCV
distribution, since the library maintains binary compatibility, and tries
to provide decent performance and stability.
%prep
%setup -q -a1 %{?with_extras:-a2}
%if 1
# we don't use pre-built contribs except quirc
pushd 3rdparty
shopt -s extglob
#rm -r !(openexr|openvx|quirc)
rm -r !(openvx|quirc|flatbuffers)
rm -r !(openvx|quirc)
shopt -u extglob
popd &>/dev/null
%endif
%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
@ -421,37 +290,23 @@ popd
# Install face_landmark_model
mkdir -p .cache/data
install -pm 0644 %{S:3} .cache/data
install -pm 0644 %{SOURCE3} .cache/data
pushd .cache/data
xz -d face_landmark_model.dat.xz
mv face_landmark_model.dat 7505c44ca4eb54b4ab1e4777cb96ac05-face_landmark_model.dat
popd
mkdir -p .cache/wechat_qrcode
mv opencv_3rdparty-%{wechat_commit}/detect.caffemodel .cache/wechat_qrcode/238e2b2d6f3c18d6c3a30de0c31e23cf-detect.caffemodel
mv opencv_3rdparty-%{wechat_commit}/detect.prototxt .cache/wechat_qrcode/6fb4976b32695f9f5c6305c19f12537d-detect.prototxt
mv opencv_3rdparty-%{wechat_commit}/sr.caffemodel .cache/wechat_qrcode/cbfcd60361a73beb8c583eea7e8e6664-sr.caffemodel
mv opencv_3rdparty-%{wechat_commit}/sr.prototxt .cache/wechat_qrcode/69db99927a70df953b471daaba03fbef-sr.prototxt
# Install ADE, needed for opencv_gapi
mkdir -p .cache/ade
install -pm 0644 %{S:4} .cache/ade/
%generate_buildrequires
cd modules/python/package
%pyproject_buildrequires
install -pm 0644 %{SOURCE4} .cache/ade/
%build
# TODO: Please submit an issue to upstream (rhbz#2381337)
export CMAKE_POLICY_VERSION_MINIMUM=3.5
# enabled by default if libraries are presents at build time:
# GTK, GSTREAMER, 1394, V4L, eigen3
# non available on Fedora: FFMPEG, XINE
# disabling IPP because it is closed source library from intel
%cmake \
%if 0%{?fedora} > 38 || 0%{?rhel} > 10
-DCMAKE_CXX_STANDARD=17 \
%endif
-DCV_TRACE=OFF \
-DWITH_IPP=OFF \
-DWITH_ITT=OFF \
@ -462,17 +317,13 @@ export CMAKE_POLICY_VERSION_MINIMUM=3.5
%endif
-DOpenGL_GL_PREFERENCE=GLVND \
-DWITH_GDAL=ON \
%{?with_openexr: -DWITH_OPENEXR=ON} \
%{!?with_openexr: -DWITH_OPENEXR=OFF} \
-DWITH_OPENEXR=ON \
-DCMAKE_SKIP_RPATH=ON \
-DWITH_CAROTENE=OFF \
%ifarch x86_64 %{ix86}
-DCPU_BASELINE=SSE2 \
%ifarch %{ix86}
-DCPU_DISPATCH=SSE4_2 \
%endif
%endif
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_BUILD_TYPE=ReleaseWithDebInfo \
%{?with_java: -DBUILD_opencv_java=ON \
-DOPENCV_JAR_INSTALL_PATH=%{_jnidir} } \
%{!?with_java: -DBUILD_opencv_java=OFF } \
@ -495,6 +346,7 @@ export CMAKE_POLICY_VERSION_MINIMUM=3.5
-DINSTALL_C_EXAMPLES=ON \
-DINSTALL_PYTHON_EXAMPLES=ON \
-DPYTHON3_EXECUTABLE=%{__python3} \
-DPYTHON3_PACKAGES_PATH=%{python3_sitearch} \
-DOPENCV_GENERATE_SETUPVARS=OFF \
%{!?with_linters: \
-DENABLE_PYLINT=OFF \
@ -502,43 +354,26 @@ export CMAKE_POLICY_VERSION_MINIMUM=3.5
} \
-DBUILD_PROTOBUF=OFF \
-DPROTOBUF_UPDATE_FILES=ON \
%{?with_opencl: -DOPENCL_INCLUDE_DIR=%{_includedir}/CL -DOPENCV_DNN_OPENCL=ON} \
%{?with_opencl: -DOPENCL_INCLUDE_DIR=%{_includedir}/CL } \
%{!?with_opencl: -DWITH_OPENCL=OFF } \
-DOPENCV_EXTRA_MODULES_PATH=opencv_contrib-%{version}/modules \
-DWITH_LIBV4L=ON \
-DWITH_OPENMP=ON \
-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_extras: -DOPENCV_TEST_DATA_PATH=opencv_extra-%{version}/testdata} \
%{?with_gdcm: -DWITH_GDCM=ON } \
-DWITH_IMGCODEC_GIF=ON \
%{?with_libmfx: -DWITH_MFX=ON -DWITH_GAPI_ONEVPL=ON} \
%{?with_libmfx: -DWITH_MFX=ON } \
%{?with_clp: -DWITH_CLP=ON } \
%{?with_libva: -DWITH_VA=ON } \
%{?with_va: -DWITH_VA=ON } \
%{!?with_vtk: -DWITH_VTK=OFF} \
%{?with_vulkan: -DWITH_VULKAN=ON -DVULKAN_INCLUDE_DIRS=%{_includedir}/vulkan }
%cmake_build
cd %{__cmake_builddir}/python_loader/
%pyproject_wheel
%install
%cmake_install
cd %{__cmake_builddir}/python_loader/
%pyproject_install
%pyproject_save_files cv2
# Hack - move the binary
%ifnarch i686
mkdir -p %{buildroot}/%{python3_sitearch}/cv2
mv %{buildroot}/%{python3_sitelib}/cv2/cv2.cpython-*-linux-gnu.so \
%{buildroot}/%{python3_sitearch}/cv2
%endif
# Correct reference in config-x.yz, keep build one for testing
mkdir test_python
cp %{buildroot}/%{python3_sitelib}/cv2/config-*.py test_python
sed -i -e "s#/builddir[^']*#%{python3_sitearch}/cv2#g" %{buildroot}/%{python3_sitelib}/cv2/config-*.py
rm -rf %{buildroot}%{_datadir}/OpenCV/licenses/
%if %{with java}
@ -547,23 +382,18 @@ ln -s -r %{buildroot}%{_jnidir}/opencv-%{javaver}.jar %{buildroot}%{_jnidir}/ope
%endif
# For compatibility with existing opencv.pc application
%{?with_compat_openvc_pc:
%{!?without_compat_openvc_pc:
ln -s opencv4.pc %{buildroot}%{_libdir}/pkgconfig/opencv.pc
}
%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/
# Check fails since we don't support most video
# read/write capability and we don't provide a display
# ARGS=-V increases output verbosity
#ifnarch ppc64
%if %{with tests}
cp %{S:5} %{__cmake_builddir}
cp %SOURCE5 .
if [ -x /usr/libexec/Xorg ]; then
Xorg=/usr/libexec/Xorg
else
@ -571,17 +401,20 @@ cp config-*.py %{buildroot}/%{python3_sitelib}/cv2/
fi
$Xorg -noreset +extension GLX +extension RANDR +extension RENDER -logfile ./xorg.log -config ./xorg.conf -configdir . :99 &
export DISPLAY=:99
%ctest || :
LD_LIBRARY_PATH=%{_builddir}/%{name}-%{version}/build/lib:$LD_LIBARY_PATH %ctest || :
%endif
#endif
%ldconfig_scriptlets core
%ldconfig_scriptlets contrib
%ldconfig_scriptlets java
%files
%doc README.md
%{_bindir}/opencv_*
%files data
%license LICENSE
%dir %{_datadir}/opencv4
%{_datadir}/opencv4/haarcascades
%{_datadir}/opencv4/lbpcascades
@ -591,13 +424,27 @@ cp config-*.py %{buildroot}/%{python3_sitelib}/cv2/
%files core
%license LICENSE
%{_datadir}/licenses/opencv4/
%{_libdir}/libopencv_calib3d.so.{%{abiver},%{version}}
%{_libdir}/libopencv_core.so.{%{abiver},%{version}}
%{_libdir}/libopencv_dnn.so.{%{abiver},%{version}}
%{_libdir}/libopencv_features2d.so.{%{abiver},%{version}}
%{_libdir}/libopencv_flann.so.{%{abiver},%{version}}
%{_libdir}/libopencv_gapi.so.{%{abiver},%{version}}
%{_libdir}/libopencv_highgui.so.{%{abiver},%{version}}
%{_libdir}/libopencv_imgcodecs.so.{%{abiver},%{version}}
%{_libdir}/libopencv_imgproc.so.{%{abiver},%{version}}
%{_libdir}/libopencv_ml.so.{%{abiver},%{version}}
%{_libdir}/libopencv_objdetect.so.{%{abiver},%{version}}
%{_libdir}/libopencv_photo.so.{%{abiver},%{version}}
%{_libdir}/libopencv_stitching.so.{%{abiver},%{version}}
%{_libdir}/libopencv_video.so.{%{abiver},%{version}}
%{_libdir}/libopencv_videoio.so.{%{abiver},%{version}}
%files devel
%dir %{_includedir}/opencv4
%{_includedir}/opencv4/opencv2
%{_libdir}/lib*.so
%{?with_compat_openvc_pc:
%{!?without_compat_openvc_pc:
%{_libdir}/pkgconfig/opencv.pc
}
%{_libdir}/pkgconfig/opencv4.pc
@ -606,14 +453,8 @@ cp config-*.py %{buildroot}/%{python3_sitelib}/cv2/
%files doc
%{_datadir}/opencv4/samples
# some files aren't properly listed
#files -n python3-opencv -f %%{pyproject_files}
%files -n python3-opencv
%{python3_sitelib}/opencv*.dist-info
%{python3_sitelib}/cv2
%ifnarch i686
%{python3_sitearch}/cv2
%endif
%if %{with java}
%files java
@ -623,226 +464,58 @@ cp config-*.py %{buildroot}/%{python3_sitelib}/cv2/
%{_jnidir}/opencv.jar
%endif
%files contrib
%{_libdir}/libopencv_alphamat.so.{%{abiver},%{version}}
%{_libdir}/libopencv_aruco.so.{%{abiver},%{version}}
%{_libdir}/libopencv_bgsegm.so.{%{abiver},%{version}}
%{_libdir}/libopencv_barcode.so.{%{abiver},%{version}}
%{_libdir}/libopencv_bioinspired.so.{%{abiver},%{version}}
%{_libdir}/libopencv_ccalib.so.{%{abiver},%{version}}
%{?with_cuda:
%{_libdir}/libopencv_cuda*.so.{%{abiver},%{version}}
%{_libdir}/libopencv_cudev.so.{%{abiver},%{version}}
}
%{_libdir}/libopencv_cvv.so.{%{abiver},%{version}}
%{_libdir}/libopencv_datasets.so.{%{abiver},%{version}}
%{_libdir}/libopencv_dnn_objdetect.so.{%{abiver},%{version}}
%{_libdir}/libopencv_dnn_superres.so.{%{abiver},%{version}}
%{_libdir}/libopencv_dpm.so.{%{abiver},%{version}}
%{_libdir}/libopencv_face.so.{%{abiver},%{version}}
%{_libdir}/libopencv_freetype.so.{%{abiver},%{version}}
%{_libdir}/libopencv_fuzzy.so.{%{abiver},%{version}}
%{_libdir}/libopencv_hdf.so.{%{abiver},%{version}}
%{_libdir}/libopencv_hfs.so.{%{abiver},%{version}}
%{_libdir}/libopencv_img_hash.so.{%{abiver},%{version}}
%{_libdir}/libopencv_intensity_transform.so.{%{abiver},%{version}}
%{_libdir}/libopencv_line_descriptor.so.{%{abiver},%{version}}
%{_libdir}/libopencv_mcc.so.{%{abiver},%{version}}
%{_libdir}/libopencv_optflow.so.{%{abiver},%{version}}
%{_libdir}/libopencv_phase_unwrapping.so.{%{abiver},%{version}}
%{_libdir}/libopencv_plot.so.{%{abiver},%{version}}
%{_libdir}/libopencv_quality.so.{%{abiver},%{version}}
%{_libdir}/libopencv_rapid.so.{%{abiver},%{version}}
%{_libdir}/libopencv_reg.so.{%{abiver},%{version}}
%{_libdir}/libopencv_rgbd.so.{%{abiver},%{version}}
%{_libdir}/libopencv_saliency.so.{%{abiver},%{version}}
%{_libdir}/libopencv_shape.so.{%{abiver},%{version}}
%{_libdir}/libopencv_stereo.so.{%{abiver},%{version}}
%{_libdir}/libopencv_structured_light.so.{%{abiver},%{version}}
%{_libdir}/libopencv_superres.so.{%{abiver},%{version}}
%{_libdir}/libopencv_surface_matching.so.{%{abiver},%{version}}
%{_libdir}/libopencv_text.so.{%{abiver},%{version}}
%{_libdir}/libopencv_tracking.so.{%{abiver},%{version}}
%{_libdir}/libopencv_videostab.so.{%{abiver},%{version}}
%if %{with vtk}
%{_libdir}/libopencv_viz.so.{%{abiver},%{version}}
%endif
%{_libdir}/libopencv_wechat_qrcode.so.{%{abiver},%{version}}
%{_libdir}/libopencv_ximgproc.so.{%{abiver},%{version}}
%{_libdir}/libopencv_xobjdetect.so.{%{abiver},%{version}}
%{_libdir}/libopencv_xphoto.so.{%{abiver},%{version}}
%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)
* Sat Nov 09 2024 Sandro Mani <manisandro@gmail.com> - 4.10.0-6
- Rebuild (gdal)
* Fri Oct 25 2024 Orion Poplawski <orion@nwra.com> - 4.10.0-5
- Rebuild for hdf5 1.14.5
* Wed Sep 25 2024 Michel Lind <salimma@fedoraproject.org> - 4.10.0-4
- Rebuild for tesseract-5.4.1-3 (soversion change from 5.4.1 to just 5.4)
* Mon Sep 23 2024 Fabio Valentini <decathorpe@gmail.com> - 4.10.0-3
- Rebuild for ffmpeg 7
* Thu Jul 25 2024 Sérgio Basto <sergio@serjux.com> - 4.10.0-2
- Rebuild for opencv 4.10.0
* Thu Jul 25 2024 Packit <hello@packit.dev> - 4.10.0-1
- Update to version 4.10.0
- Resolves: rhbz#2290312
* Thu Jul 18 2024 Fedora Release Engineering <releng@fedoraproject.org> - 4.9.0-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
* Thu Jun 13 2024 Sandro Mani <manisandro@gmail.com> - 4.9.0-7
- Rebuild for tesseract-5.4.1
* Sun Jun 09 2024 Python Maint <python-maint@redhat.com> - 4.9.0-6
- Rebuilt for Python 3.13
* Tue May 14 2024 Sandro Mani <manisandro@gmail.com> - 4.9.0-5
- Rebuild (gdal)
* Tue Apr 23 2024 Josef Ridky <jridky@redhat.com> - 4.9.0-4
- Rebuild for openexr
* Fri Feb 23 2024 Jerry James <loganjerry@gmail.com> - 4.9.0-3
- Rebuild (coin-or-Clp)
- Use uppercase connectives in SPDX expression
* Mon Feb 05 2024 Sérgio Basto <sergio@serjux.com> - 4.9.0-2
- Revert "drop compat symlink to opencv.pc"
* Sun Jan 28 2024 Sérgio Basto <sergio@serjux.com> - 4.9.0-1
- Update opencv to 4.9.0 (#2256160)
- Enable ffmpeg and xine (now they are available on Fedora)
- Really drop compat symlink for includes - rhbz#1830266
Note: conditional builds with underscrore don't have _without option
https://github.com/rpm-software-management/rpm/issues/1929
* Sun Jan 28 2024 Sandro Mani <manisandro@gmail.com> - 4.8.1-8
- Rebuild (tesseract)
* Thu Jan 25 2024 Fedora Release Engineering <releng@fedoraproject.org> - 4.8.1-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org> - 4.8.1-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Wed Jan 17 2024 Jonathan Wakely <jwakely@redhat.com> - 4.8.1-5
- Rebuilt for TBB 2021.11
* Thu Jan 11 2024 Benjamin A. Beasley <code@musicinmybrain.net> - 4.8.1-4
- Backport support for protobuf v22 and later from opencv 4.9.0
* Thu Nov 16 2023 Sandro Mani <manisandro@gmail.com> - 4.8.1-3
- Rebuild (gdal)
* Sat Oct 07 2023 Sandro Mani <manisandro@gmail.com> - 4.8.1-2
- Rebuild (tesseract)
* Fri Sep 29 2023 Sérgio Basto <sergio@serjux.com> - 4.8.1-1
- Update opencv to 4.8.1
* Thu Sep 14 2023 Yaakov Selkowitz <yselkowi@redhat.com> - 4.8.0-2
- Separate per-module subpackages (#1878320)
* Mon Aug 07 2023 Sérgio Basto <sergio@serjux.com> - 4.8.0-1
- Update opencv to 4.8.0
- Use bundle flatbuffers, tried build with flatbuffers from system but doesn't build
- Use oneVPL instead libmfx
- Add WeChat QRCode
- https://src.fedoraproject.org/rpms/opencv/pull-request/23 , upgrade C++ standard to C++17 for protobuf v4 (23.x etc.)
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 4.7.0-15
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Wed Jul 19 2023 Josef Ridky <jridky@redhat.com> - 4.7.0-14
- Migrate to SPDX license format
* Fri Jul 14 2023 Sandro Mani <manisandro@gmail.com> - 4.7.0-13
- Rebuild (tesseract)
* Fri Jul 07 2023 Mamoru TASAKA <mtasaka@fedoraproject.org> - 4.7.0-12
- Drop openni support on i686 as it is no longer available
* Mon Jul 03 2023 Python Maint <python-maint@redhat.com> - 4.7.0-11
- Rebuilt for Python 3.12
* Mon Jun 12 2023 Nicolas Chauvet <kwizart@gmail.com> - 4.7.0-10
- Rebuilt for libdc1394
* Mon Jun 12 2023 Nicolas Chauvet <kwizart@gmail.com> - 4.7.0-9
- Upstream commit to fix rhbz#2190013
* Sat May 13 2023 Sérgio Basto <sergio@serjux.com> - 4.7.0-8
- The %%ldconfig_scriptlets macro can be removed on all Fedoras. Possibly also on
EPEL 8. But it is required on EPEL 7.
- Install egg-info in python3_sitearch to stay in same location as the rest of python
* Sat May 13 2023 Sérgio Basto <sergio@serjux.com> - 4.7.0-7
- Install python egg-info
- Fix patch warning
- Obsolete python2 < %{version} (if someone want use an external python2 version}
* Thu May 11 2023 Sandro Mani <manisandro@gmail.com> - 4.7.0-6
- Rebuild (gdal)
- Disable tests, even only tests, fail to build and generate build.log with millions of logs lines saying:
*** stack smashing detected ***: terminated
cat build.log | grep smashing | wc -l
118308609
- Disable extra tests on builds
* Thu Apr 13 2023 Sérgio Basto <sergio@serjux.com> - 4.7.0-5
- if without tests also disable 500MB of extra tests
* Mon Apr 03 2023 Sandro Mani <manisandro@gmail.com> - 4.7.0-4
- Rebuild (tesseract)
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 4.7.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Sun Jan 15 2023 Orion Poplawski <orion@nwra.com> - 4.7.0-2
- Rebuild for vtk 9.2.5
* Fri Jan 13 2023 Sérgio Basto <sergio@serjux.com> - 4.7.0-1
- Update opencv to 4.7.0 (#2157121)
* Fri Dec 23 2022 Sandro Mani <manisandro@gmail.com> - 4.6.0-10
- Rebuild (tesseract)
* Fri Dec 23 2022 Nicolas Chauvet <kwizart@gmail.com> - 4.6.0-9
- Rebuilt for tesseract
* Sat Nov 12 2022 Sandro Mani <manisandro@gmail.com> - 4.6.0-8
- Rebuild (gdal)
* Tue Jul 29 2025 Nicolas Chauvet <kwizart@gmail.com>
- Rebuilt for gdal - rhbz#2383114
* Wed Sep 28 2022 Tom Rix <trix@redhat.com> - 4.6.0-7
- Remove Unicap

View file

@ -1,11 +0,0 @@
--- opencv-4.11.0/modules/highgui/CMakeLists.txt 2025-01-08 04:47:46.000000000 -0800
+++ opencv-4.11.0/modules/highgui/CMakeLists.txt.new 2025-07-08 15:54:10.138078285 -0700
@@ -125,7 +125,7 @@
endif()
foreach(dt_dep ${qt_deps})
- add_definitions(${Qt${QT_VERSION_MAJOR}${dt_dep}_DEFINITIONS})
+ link_libraries(${Qt${QT_VERSION_MAJOR}${dt_dep}})
include_directories(${Qt${QT_VERSION_MAJOR}${dt_dep}_INCLUDE_DIRS})
list(APPEND HIGHGUI_LIBRARIES ${Qt${QT_VERSION_MAJOR}${dt_dep}_LIBRARIES})
endforeach()

View file

@ -1,5 +1,5 @@
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-clean-4.6.0.tar.gz) = 73815df0df4b93b3df19d66e0957a781de25c78ee51d0f026129df9302d45b114bf3cd249ed13121c160df7b4c01b9e348fe2ba75949d3e25fe6f6168d2b0576
SHA512 (opencv_contrib-clean-4.6.0.tar.gz) = 8f4a6569671eb161beac6c9bc52f51b3a9e1ac257478477d5238ddcac959612055ab8554a5815f5b55fe8405a34885e63c1c9995468e5641b9d47d1120ef0113
SHA512 (opencv_extra-clean-4.6.0.tar.gz) = 2b576a2ed87e1a41fddb351bbc66fa23397aa6952866aec3d172976d261f035dc0c1f3e7c66e85e0684bb050862c368fe7fdc34804a9c6171cf1b2a96b621a33
SHA512 (face_landmark_model.dat.xz) = 7558f29431bb9cad1f22ee067ad3ed41be8f68b865992eb7d3a5ce6b6b9e1d031cb03e33c3c149220ef8faebd0471703a8a3bbb06402bcc8ce76bd28317aa307
SHA512 (962ce79e0b95591f226431f7b5f152cd-v0.1.2e.zip) = 87c65716498ca2e4f64fb9a1f78f7e5c48fffff5fc6735027edfb7d7ccc0d9f5b01c85f4b956ddc7e1c35c69ee2513d48a7da91764c2fd01d073ee5a1fc90c6f
SHA512 (b624b995ec9c439cbc2e9e6ee940d3a2-v0.1.1f.zip) = f2994d5e92a2ae05cee6e153943afe151ce734ced6e06dcdb02dee9fed9336a7f1ea69661d9e033f1412fbb5e2a44a6e641662c85be5ba0604d0446abeabe836