1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2025-09-26 09:24:38 +03:00
91 changed files with 5339 additions and 1508 deletions
+15 -5
View File
@@ -59,7 +59,17 @@ void RBaseStream::readBlock()
throw RBS_THROW_EOS;
}
#ifdef _WIN32
// See https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fseek-fseeki64?view=msvc-170
// See https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models
// - Windows uses LLP64 data model, sizeof long int = 32.
// - Linux uses LP64 data model, sizeof long int = 64.
// So for Windows, we have to use _fseeki64() instead of fseek().
_fseeki64( m_file, m_block_pos, SEEK_SET );
#else
fseek( m_file, m_block_pos, SEEK_SET );
#endif
size_t readed = fread( m_start, 1, m_block_size, m_file );
m_end = m_start + readed;
@@ -120,7 +130,7 @@ void RBaseStream::release()
}
void RBaseStream::setPos( int pos )
void RBaseStream::setPos( int64_t pos )
{
CV_Assert(isOpened() && pos >= 0);
@@ -132,7 +142,7 @@ void RBaseStream::setPos( int pos )
}
int offset = pos % m_block_size;
int old_block_pos = m_block_pos;
int64_t old_block_pos = m_block_pos;
m_block_pos = pos - offset;
m_current = m_start + offset;
if (old_block_pos != m_block_pos)
@@ -140,16 +150,16 @@ void RBaseStream::setPos( int pos )
}
int RBaseStream::getPos()
int64_t RBaseStream::getPos()
{
CV_Assert(isOpened());
int pos = validateToInt((m_current - m_start) + m_block_pos);
int64_t pos = validateToInt64((m_current - m_start) + m_block_pos);
CV_Assert(pos >= m_block_pos); // overflow check
CV_Assert(pos >= 0); // overflow check
return pos;
}
void RBaseStream::skip( int bytes )
void RBaseStream::skip( int64_t bytes )
{
CV_Assert(bytes >= 0);
uchar* old = m_current;
+4 -4
View File
@@ -45,9 +45,9 @@ public:
virtual bool open( const Mat& buf );
virtual void close();
bool isOpened();
void setPos( int pos );
int getPos();
void skip( int bytes );
void setPos( int64_t pos );
int64_t getPos();
void skip( int64_t bytes );
protected:
@@ -57,7 +57,7 @@ protected:
uchar* m_current;
FILE* m_file;
int m_block_size;
int m_block_pos;
int64_t m_block_pos;
bool m_is_opened;
virtual void readBlock();
-3
View File
@@ -237,9 +237,6 @@ bool BmpDecoder::readData( Mat& img )
int nch = color ? 3 : 1;
int y, width3 = m_width*nch;
// FIXIT: use safe pointer arithmetic (avoid 'int'), use size_t, intptr_t, etc
CV_Assert(((uint64)m_height * m_width * nch < (CV_BIG_UINT(1) << 30)) && "BMP reader implementation doesn't support large images >= 1Gb");
if( m_offset < 0 || !m_strm.isOpened())
return false;
+1 -1
View File
@@ -87,7 +87,7 @@ protected:
PaletteEntry m_palette[256];
Origin m_origin;
int m_bpp;
int m_offset;
int64_t m_offset;
BmpCompression m_rle_code;
uint m_rgba_mask[4];
int m_rgba_bit_offset[4];
+2 -2
View File
@@ -78,8 +78,8 @@ public:
protected:
RLByteStream m_strm;
int m_maxval, m_channels, m_sampledepth, m_offset,
selected_fmt;
int64_t m_offset;
int m_maxval, m_channels, m_sampledepth, selected_fmt;
bool bit_mode;
};
+163 -122
View File
@@ -434,138 +434,147 @@ bool PngDecoder::readData( Mat& img )
if (!processing_start((void*)&frameRaw, mat_cur))
return false;
while (true)
// See https://github.com/opencv/opencv/issues/27744
if( setjmp( png_jmpbuf ( m_png_ptr ) ) == 0 )
{
id = read_chunk(chunk);
if (!id)
return false;
if (id == id_fcTL && m_is_IDAT_loaded)
while (true)
{
if (!m_is_fcTL_loaded)
id = read_chunk(chunk);
if (!id)
return false;
if (id == id_fcTL && m_is_IDAT_loaded)
{
m_mat_raw.copyTo(m_animation.still_image);
}
else
{
if (processing_finish())
if (!m_is_fcTL_loaded)
{
if (dop == 2)
memcpy(frameNext.getPixels(), frameCur.getPixels(), imagesize);
if (x0 + w0 > frameCur.getWidth() || y0 + h0 > frameCur.getHeight())
return false;
compose_frame(frameCur.getRows(), frameRaw.getRows(), bop, x0, y0, w0, h0, mat_cur);
if (!delay_den)
delay_den = 100;
m_animation.durations.push_back(cvRound(1000. * delay_num / delay_den));
if (mat_cur.channels() == img.channels())
m_mat_raw.copyTo(m_animation.still_image);
}
else
{
if (processing_finish())
{
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
mat_cur.convertTo(img, CV_8U, 1. / 255);
if (dop == 2)
memcpy(frameNext.getPixels(), frameCur.getPixels(), imagesize);
if (x0 + w0 > frameCur.getWidth() || y0 + h0 > frameCur.getHeight())
return false;
compose_frame(frameCur.getRows(), frameRaw.getRows(), bop, x0, y0, w0, h0, mat_cur);
if (!delay_den)
delay_den = 100;
m_animation.durations.push_back(cvRound(1000. * delay_num / delay_den));
if (mat_cur.channels() == img.channels())
{
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
mat_cur.convertTo(img, CV_8U, 1. / 255);
else
mat_cur.copyTo(img);
}
else
mat_cur.copyTo(img);
{
Mat mat_cur_scaled;
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
mat_cur.convertTo(mat_cur_scaled, CV_8U, 1. / 255);
else
mat_cur_scaled = mat_cur;
if (img.channels() == 1)
cvtColor(mat_cur_scaled, img, COLOR_BGRA2GRAY);
else if (img.channels() == 3)
cvtColor(mat_cur_scaled, img, COLOR_BGRA2BGR);
}
if (dop != 2)
{
memcpy(frameNext.getPixels(), frameCur.getPixels(), imagesize);
if (dop == 1)
for (j = 0; j < h0; j++)
memset(frameNext.getRows()[y0 + j] + x0 * img.channels(), 0, w0 * img.channels());
}
}
else
{
Mat mat_cur_scaled;
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
mat_cur.convertTo(mat_cur_scaled, CV_8U, 1. / 255);
else
mat_cur_scaled = mat_cur;
if (img.channels() == 1)
cvtColor(mat_cur_scaled, img, COLOR_BGRA2GRAY);
else if (img.channels() == 3)
cvtColor(mat_cur_scaled, img, COLOR_BGRA2BGR);
return false;
}
}
if (dop != 2)
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 (int(x0 + w0) > img.cols || int(y0 + h0) > img.rows || dop > 2 || bop > 1)
{
return false;
}
memcpy(&m_chunkIHDR.p[8], &chunk.p[12], 8);
if (m_is_fcTL_loaded)
return true;
else
{
m_is_fcTL_loaded = true;
ClearPngPtr();
if (!processing_start((void*)&frameRaw, mat_cur))
return false;
}
}
else if (id == id_IDAT)
{
m_is_IDAT_loaded = true;
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(m_png_ptr, m_info_ptr, &chunk.p[4], chunk.p.size() - 4);
}
else if (id == id_IEND)
{
if (processing_finish())
{
compose_frame(frameCur.getRows(), frameRaw.getRows(), bop, x0, y0, w0, h0, mat_cur);
if (!delay_den)
delay_den = 100;
m_animation.durations.push_back(cvRound(1000.*delay_num/delay_den));
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U && mat_cur.channels() == img.channels())
mat_cur.convertTo(img, CV_8U, 1. / 255);
else
{
memcpy(frameNext.getPixels(), frameCur.getPixels(), imagesize);
if (dop == 1)
for (j = 0; j < h0; j++)
memset(frameNext.getRows()[y0 + j] + x0 * img.channels(), 0, w0 * img.channels());
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
mat_cur.convertTo(mat_cur, CV_8U, 1. / 255);
if (mat_cur.channels() == img.channels())
mat_cur.copyTo(img);
else if (img.channels() == 1)
cvtColor(mat_cur, img, COLOR_BGRA2GRAY);
else if (img.channels() == 3)
cvtColor(mat_cur, img, COLOR_BGRA2BGR);
}
}
else
{
return false;
}
}
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 (int(x0 + w0) > img.cols || int(y0 + h0) > img.rows || dop > 2 || bop > 1)
{
return false;
}
memcpy(&m_chunkIHDR.p[8], &chunk.p[12], 8);
if (m_is_fcTL_loaded)
return true;
else
{
m_is_fcTL_loaded = true;
ClearPngPtr();
if (!processing_start((void*)&frameRaw, mat_cur))
return false;
}
}
else if (id == id_IDAT)
{
m_is_IDAT_loaded = true;
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(m_png_ptr, m_info_ptr, &chunk.p[4], chunk.p.size() - 4);
}
else if (id == id_IEND)
{
if (processing_finish())
{
compose_frame(frameCur.getRows(), frameRaw.getRows(), bop, x0, y0, w0, h0, mat_cur);
if (!delay_den)
delay_den = 100;
m_animation.durations.push_back(cvRound(1000.*delay_num/delay_den));
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U && mat_cur.channels() == img.channels())
mat_cur.convertTo(img, CV_8U, 1. / 255);
else
{
if (mat_cur.depth() == CV_16U && img.depth() == CV_8U)
mat_cur.convertTo(mat_cur, CV_8U, 1. / 255);
if (mat_cur.channels() == img.channels())
mat_cur.copyTo(img);
else if (img.channels() == 1)
cvtColor(mat_cur, img, COLOR_BGRA2GRAY);
else if (img.channels() == 3)
cvtColor(mat_cur, img, COLOR_BGRA2BGR);
}
}
else
return false;
return true;
png_process_data(m_png_ptr, m_info_ptr, chunk.p.data(), chunk.p.size());
}
else
png_process_data(m_png_ptr, m_info_ptr, chunk.p.data(), chunk.p.size());
return false;
}
else
{
// libpng internal error is detected.
return false;
}
return false;
}
volatile bool result = false;
@@ -1621,20 +1630,52 @@ bool PngEncoder::writeanimation(const Animation& animation, const std::vector<in
for (size_t i = 0; i < params.size(); i += 2)
{
if (params[i] == IMWRITE_PNG_COMPRESSION)
const int value = params[i+1];
switch (params[i])
{
case IMWRITE_PNG_COMPRESSION:
m_compression_strategy = IMWRITE_PNG_STRATEGY_DEFAULT; // Default strategy
m_compression_level = params[i + 1];
m_compression_level = MIN(MAX(m_compression_level, 0), Z_BEST_COMPRESSION);
}
if (params[i] == IMWRITE_PNG_STRATEGY)
{
m_compression_strategy = params[i + 1];
m_compression_strategy = MIN(MAX(m_compression_strategy, 0), Z_FIXED);
}
if (params[i] == IMWRITE_PNG_BILEVEL)
{
m_isBilevel = params[i + 1] != 0;
m_compression_level = MIN(MAX(value, 0), Z_BEST_COMPRESSION);
if(value != m_compression_level) {
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_COMPRESSION must be between 0 to 9. It is fallbacked to %d", value, m_compression_level));
}
break;
case IMWRITE_PNG_STRATEGY:
{
switch(value) {
case IMWRITE_PNG_STRATEGY_DEFAULT:
case IMWRITE_PNG_STRATEGY_FILTERED:
case IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY:
case IMWRITE_PNG_STRATEGY_RLE:
case IMWRITE_PNG_STRATEGY_FIXED:
m_compression_strategy = value;
break;
default:
m_compression_strategy = IMWRITE_PNG_STRATEGY_RLE;
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_STRATEGY must be one of ImwritePNGFlags. It is fallbacked to IMWRITE_PNG_STRATEGY_RLE", value));
break;
}
}
break;
case IMWRITE_PNG_BILEVEL:
m_isBilevel = value != 0;
if((value != 0) && (value != 1)) {
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_BILEVEL must be 0 or 1. It is fallbacked to 1", value ));
}
break;
case IMWRITE_PNG_FILTER:
CV_LOG_WARNING(nullptr, "IMWRITE_PNG_BILEVEL parameter is not supported for APNG");
break;
case IMWRITE_PNG_ZLIBBUFFER_SIZE:
CV_LOG_WARNING(nullptr, "IMWRITE_PNG_ZLIBBUFFER_SIZE parameter is not supported for APNG");
break;
default:
break;
}
}
+1 -1
View File
@@ -79,7 +79,7 @@ protected:
RLByteStream m_strm;
PaletteEntry m_palette[256];
int m_bpp;
int m_offset;
int64_t m_offset;
bool m_binary;
int m_maxval;
};
+3 -3
View File
@@ -540,8 +540,8 @@ bool SPngEncoder::write(const Mat &img, const std::vector<int> &params)
{
compression_strategy = IMWRITE_PNG_STRATEGY_DEFAULT; // Default strategy
compression_level = MIN(MAX(value, 0), Z_BEST_COMPRESSION);
if(value != m_compression_level) {
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_COMPRESSION must be between 0 to 9. It is fallbacked to %d", value, m_compression_level));
if(value != compression_level) {
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_COMPRESSION must be between 0 to 9. It is fallbacked to %d", value, compression_level));
}
set_compression_level = true;
}
@@ -556,7 +556,7 @@ bool SPngEncoder::write(const Mat &img, const std::vector<int> &params)
compression_strategy = value;
break;
default:
compression_strategy = IMWRITE_PNG_STRATEGY_RLE:
compression_strategy = IMWRITE_PNG_STRATEGY_RLE;
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_PNG_STRATEGY must be one of ImwritePNGFlags. It is fallbacked to IMWRITE_PNG_STRATEGY_RLE", value));
break;
}
+2 -2
View File
@@ -94,7 +94,7 @@ bool SunRasterDecoder::readHeader()
m_type = IsColorPalette( m_palette, m_bpp ) ? CV_8UC3 : CV_8UC1;
m_offset = m_strm.getPos();
CV_Assert(m_offset == 32 + m_maplength);
CV_Assert(m_offset == static_cast<int64_t>(32 + m_maplength));
result = true;
}
}
@@ -107,7 +107,7 @@ bool SunRasterDecoder::readHeader()
m_offset = m_strm.getPos();
CV_Assert(m_offset == 32 + m_maplength);
CV_Assert(m_offset == static_cast<int64_t>(32 + m_maplength));
result = true;
}
}
+1 -1
View File
@@ -84,7 +84,7 @@ protected:
RMByteStream m_strm;
PaletteEntry m_palette[256];
int m_bpp;
int m_offset;
int64_t m_offset;
SunRasType m_encoding;
SunRasMapType m_maptype;
int m_maplength;
+10 -7
View File
@@ -511,23 +511,26 @@ bool WebPEncoder::writeanimation(const Animation& animation, const std::vector<i
anim_config.anim_params.bgcolor = bgvalue;
anim_config.anim_params.loop_count = animation.loop_count;
anim_config.minimize_size = 0;
if (params.size() > 1)
for(size_t i = 0; i < params.size(); i += 2)
{
if (params[0] == IMWRITE_WEBP_QUALITY)
const int value = params[i+1];
if (params[i] == IMWRITE_WEBP_QUALITY)
{
config.lossless = 0;
config.quality = static_cast<float>(params[1]);
config.lossless = 0; // false
config.quality = static_cast<float>(value);
if (config.quality < 1.0f)
{
config.quality = 1.0f;
CV_LOG_WARNING(nullptr, cv::format("The value(%d) for IMWRITE_WEBP_QUALITY must be between 1 to 100(lossy) or more(lossless). It is fallbacked to 1", value));
}
if (config.quality >= 100.0f)
if (config.quality > 100.0f)
{
config.lossless = 1;
config.quality = 100.0f;
config.lossless = 1; // true
}
}
anim_config.minimize_size = 0;
}
std::unique_ptr<WebPAnimEncoder, void (*)(WebPAnimEncoder*)> anim_encoder(
+7
View File
@@ -51,6 +51,13 @@ int validateToInt(size_t sz)
return valueInt;
}
int64_t validateToInt64(size_t sz)
{
int64_t valueInt = static_cast<int64_t>(sz);
CV_Assert((size_t)valueInt == sz);
return valueInt;
}
#define SCALE 14
#define cR (int)(0.299*(1 << SCALE) + 0.5)
#define cG (int)(0.587*(1 << SCALE) + 0.5)
+1
View File
@@ -45,6 +45,7 @@
namespace cv {
int validateToInt(size_t step);
int64_t validateToInt64(size_t step);
template <typename _Tp> static inline
size_t safeCastToSizeT(const _Tp v_origin, const char* msg)