Do not release user-provided buffer, if decoder failed.

pull/24929/head
Alexander Smorkalov 1 year ago
parent efc9837df1
commit c9671da732
  1. 3
      modules/imgcodecs/include/opencv2/imgcodecs.hpp
  2. 17
      modules/imgcodecs/src/loadsave.cpp
  3. 13
      modules/imgcodecs/test/test_grfmt.cpp

@ -322,7 +322,8 @@ CV_EXPORTS_W Mat imdecode( InputArray buf, int flags );
@param buf Input array or vector of bytes.
@param flags The same flags as in cv::imread, see cv::ImreadModes.
@param dst The optional output placeholder for the decoded matrix. It can save the image
reallocations when the function is called repeatedly for images of the same size.
reallocations when the function is called repeatedly for images of the same size. In case of decoder
failure the function returns empty cv::Mat object, but does not release user-provided dst buffer.
*/
CV_EXPORTS Mat imdecode( InputArray buf, int flags, Mat* dst);

@ -800,7 +800,7 @@ imdecode_( const Mat& buf, int flags, Mat& mat )
ImageDecoder decoder = findDecoder(buf_row);
if( !decoder )
return 0;
return false;
int scale_denom = 1;
if( flags > IMREAD_LOAD_GDAL )
@ -821,7 +821,7 @@ imdecode_( const Mat& buf, int flags, Mat& mat )
filename = tempfile();
FILE* f = fopen( filename.c_str(), "wb" );
if( !f )
return 0;
return false;
size_t bufSize = buf_row.total()*buf.elemSize();
if (fwrite(buf_row.ptr(), 1, bufSize, f) != bufSize)
{
@ -859,7 +859,7 @@ imdecode_( const Mat& buf, int flags, Mat& mat )
CV_LOG_WARNING(NULL, "unable to remove temporary file:" << filename);
}
}
return 0;
return false;
}
// established the required input image size
@ -905,7 +905,6 @@ imdecode_( const Mat& buf, int flags, Mat& mat )
if (!success)
{
mat.release();
return false;
}
@ -929,7 +928,8 @@ Mat imdecode( InputArray _buf, int flags )
CV_TRACE_FUNCTION();
Mat buf = _buf.getMat(), img;
imdecode_( buf, flags, img );
if (!imdecode_(buf, flags, img))
img.release();
return img;
}
@ -940,9 +940,10 @@ Mat imdecode( InputArray _buf, int flags, Mat* dst )
Mat buf = _buf.getMat(), img;
dst = dst ? dst : &img;
imdecode_( buf, flags, *dst );
return *dst;
if (imdecode_(buf, flags, *dst))
return *dst;
else
return cv::Mat();
}
static bool

@ -482,6 +482,19 @@ TEST(Imgcodecs, write_parameter_type)
EXPECT_EQ(0, remove(tmp_file.c_str()));
}
TEST(Imgcodecs, imdecode_user_buffer)
{
cv::Mat encoded = cv::Mat::zeros(1, 1024, CV_8UC1);
cv::Mat user_buffer(1, 1024, CV_8UC1);
cv::Mat result = cv::imdecode(encoded, IMREAD_ANYCOLOR, &user_buffer);
EXPECT_TRUE(result.empty());
// the function does not release user-provided buffer
EXPECT_FALSE(user_buffer.empty());
result = cv::imdecode(encoded, IMREAD_ANYCOLOR);
EXPECT_TRUE(result.empty());
}
}} // namespace
#if defined(HAVE_OPENEXR) && defined(OPENCV_IMGCODECS_ENABLE_OPENEXR_TESTS)

Loading…
Cancel
Save