mirror of
https://github.com/zebrajr/opencv.git
synced 2025-12-06 00:19:46 +01:00
png: add setjmp() to detect libpng internal error
This commit is contained in:
parent
6d889ee74c
commit
d9572861d1
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user