// Utility function for safe integer conversions
template <typename D, typename S>
-inline D safe_int_cast(S val)
+inline D safe_int_cast(S val, const char * msg = 0)
{
typedef std::numeric_limits<S> st;
typedef std::numeric_limits<D> dt;
const bool in_range_l = (double)val >= (double)dt::min();
if (!in_range_r || !in_range_l)
{
- CV_Error_(cv::Error::StsOutOfRange, ("Can not convert integer values (%s -> %s), value 0x%llx is out of range", typeid(S).name(), typeid(D).name(), val));
+ if (!msg)
+ CV_Error_(Error::StsOutOfRange, ("Can not convert integer values (%s -> %s), value 0x%llx is out of range", typeid(S).name(), typeid(D).name(), val));
+ else
+ CV_Error(Error::StsOutOfRange, msg);
}
return static_cast<D>(val);
}
VideoInputStream();
VideoInputStream(const String& filename);
~VideoInputStream();
- VideoInputStream& read(char*, uint64_t);
+ VideoInputStream& read(char*, uint32_t);
VideoInputStream& seekg(uint64_t);
uint64_t tellg();
bool isOpened() const;
}
}
-VideoInputStream& VideoInputStream::read(char* buf, uint64_t count)
+VideoInputStream& VideoInputStream::read(char* buf, uint32_t count)
{
if(isOpened())
{
- input.read(buf, safe_int_cast<std::streamsize>(count));
+ input.read(buf, safe_int_cast<std::streamsize>(count, "Failed to read AVI file: requested chunk size is too large"));
m_is_valid = (input.gcount() == (std::streamsize)count);
}
VideoInputStream& VideoInputStream::seekg(uint64_t pos)
{
input.clear();
- input.seekg(safe_int_cast<std::streamoff>(pos));
+ input.seekg(safe_int_cast<std::streamoff>(pos, "Failed to seek in AVI file: position is out of range"));
m_is_valid = !input.eof();
return *this;
}
}
size_t BitStream::getPos() const {
- return safe_int_cast<size_t>(m_current - m_start) + m_pos;
+ return safe_int_cast<size_t>(m_current - m_start, "Failed to determine AVI bufer position: value is out of range") + m_pos;
}
void BitStream::putByte(int val)
{
if( pos >= m_pos )
{
- ptrdiff_t delta = safe_int_cast<ptrdiff_t>(pos - m_pos);
+ ptrdiff_t delta = safe_int_cast<ptrdiff_t>(pos - m_pos, "Failed to seek in AVI buffer: value is out of range");
CV_Assert( delta < m_current - m_start );
m_start[delta] = (uchar)val;
m_start[delta+1] = (uchar)(val >> 8);
else
{
std::streamoff fpos = output.tellp();
- output.seekp(safe_int_cast<std::streamoff>(pos));
+ output.seekp(safe_int_cast<std::streamoff>(pos, "Failed to seek in AVI file: value is out of range"));
uchar buf[] = { (uchar)val, (uchar)(val >> 8), (uchar)(val >> 16), (uchar)(val >> 24) };
output.write((char *)buf, 4);
output.seekp(fpos);
size_t pospos = AVIChunkSizeIndex.back();
AVIChunkSizeIndex.pop_back();
CV_Assert(currpos >= pospos);
- uint32_t chunksz = safe_int_cast<uint32_t>(currpos - pospos);
+ uint32_t chunksz = safe_int_cast<uint32_t>(currpos - pospos, "Failed to write AVI file: chunk size is out of bounds");
strm->patchInt(chunksz, pospos);
}
}
void AVIWriteContainer::finishWriteAVI()
{
- uint32_t nframes = safe_int_cast<uint32_t>(frameOffset.size());
+ uint32_t nframes = safe_int_cast<uint32_t>(frameOffset.size(), "Failed to write AVI file: number of frames is too large");
// Record frames numbers to AVI Header
while (!frameNumIndexes.empty())
{