diff --git a/modules/imgcodecs/src/bitstrm.cpp b/modules/imgcodecs/src/bitstrm.cpp index 97df645a6d..a8f91aa4dd 100644 --- a/modules/imgcodecs/src/bitstrm.cpp +++ b/modules/imgcodecs/src/bitstrm.cpp @@ -377,26 +377,30 @@ void WBaseStream::allocate() } -void WBaseStream::writeBlock() +bool WBaseStream::writeBlock() { int size = (int)(m_current - m_start); CV_Assert(isOpened()); if( size == 0 ) - return; + return true; if( m_buf ) { size_t sz = m_buf->size(); m_buf->resize( sz + size ); memcpy( &(*m_buf)[sz], m_start, size ); + m_current = m_start; + m_block_pos += size; + return true; } else { - fwrite( m_start, 1, size, m_file ); + size_t written = fwrite( m_start, 1, size, m_file ); + m_current = m_start; + m_block_pos += size; + return written == (size_t)size; } - m_current = m_start; - m_block_pos += size; } @@ -463,15 +467,17 @@ WLByteStream::~WLByteStream() { } -void WLByteStream::putByte( int val ) +bool WLByteStream::putByte( int val ) { *m_current++ = (uchar)val; if( m_current >= m_end ) - writeBlock(); + return writeBlock(); + + return true; } -void WLByteStream::putBytes( const void* buffer, int count ) +bool WLByteStream::putBytes( const void* buffer, int count ) { uchar* data = (uchar*)buffer; @@ -492,12 +498,18 @@ void WLByteStream::putBytes( const void* buffer, int count ) count -= l; } if( m_current == m_end ) - writeBlock(); + { + bool written = writeBlock(); + if (!written) + return false; + } } + + return true; } -void WLByteStream::putWord( int val ) +bool WLByteStream::putWord( int val ) { uchar *current = m_current; @@ -507,17 +519,19 @@ void WLByteStream::putWord( int val ) current[1] = (uchar)(val >> 8); m_current = current + 2; if( m_current == m_end ) - writeBlock(); + return writeBlock(); } else { putByte(val); putByte(val >> 8); } + + return true; } -void WLByteStream::putDWord( int val ) +bool WLByteStream::putDWord( int val ) { uchar *current = m_current; @@ -529,7 +543,7 @@ void WLByteStream::putDWord( int val ) current[3] = (uchar)(val >> 24); m_current = current + 4; if( m_current == m_end ) - writeBlock(); + return writeBlock(); } else { @@ -538,6 +552,8 @@ void WLByteStream::putDWord( int val ) putByte(val >> 16); putByte(val >> 24); } + + return true; } @@ -548,7 +564,7 @@ WMByteStream::~WMByteStream() } -void WMByteStream::putWord( int val ) +bool WMByteStream::putWord( int val ) { uchar *current = m_current; @@ -558,17 +574,19 @@ void WMByteStream::putWord( int val ) current[1] = (uchar)val; m_current = current + 2; if( m_current == m_end ) - writeBlock(); + return writeBlock(); } else { putByte(val >> 8); putByte(val); } + + return true; } -void WMByteStream::putDWord( int val ) +bool WMByteStream::putDWord( int val ) { uchar *current = m_current; @@ -580,7 +598,7 @@ void WMByteStream::putDWord( int val ) current[3] = (uchar)val; m_current = current + 4; if( m_current == m_end ) - writeBlock(); + return writeBlock(); } else { @@ -589,6 +607,8 @@ void WMByteStream::putDWord( int val ) putByte(val >> 8); putByte(val); } + + return true; } } diff --git a/modules/imgcodecs/src/bitstrm.hpp b/modules/imgcodecs/src/bitstrm.hpp index 26947971f3..ebffb91f10 100644 --- a/modules/imgcodecs/src/bitstrm.hpp +++ b/modules/imgcodecs/src/bitstrm.hpp @@ -63,6 +63,12 @@ DECLARE_RBS_EXCEPTION(THROW_FORB) DECLARE_RBS_EXCEPTION(BAD_HEADER) #define RBS_BAD_HEADER RBS_BAD_HEADER_Exception(cv::Error::StsError, "Invalid header", CV_Func, __FILE__, __LINE__) +#define CHECK_WRITE(action) \ +if (!action) \ +{ \ + return false; \ +} + typedef unsigned long ulong; // class RBaseStream - base class for other reading streams. @@ -147,7 +153,7 @@ protected: bool m_is_opened; std::vector* m_buf; - virtual void writeBlock(); + virtual bool writeBlock(); virtual void release(); virtual void allocate(); }; @@ -160,10 +166,10 @@ class WLByteStream : public WBaseStream public: virtual ~WLByteStream(); - void putByte( int val ); - void putBytes( const void* buffer, int count ); - void putWord( int val ); - void putDWord( int val ); + bool putByte( int val ); + bool putBytes( const void* buffer, int count ); + bool putWord( int val ); + bool putDWord( int val ); }; @@ -173,8 +179,8 @@ class WMByteStream : public WLByteStream { public: virtual ~WMByteStream(); - void putWord( int val ); - void putDWord( int val ); + bool putWord( int val ); + bool putDWord( int val ); }; inline unsigned BSWAP(unsigned v) diff --git a/modules/imgcodecs/src/grfmt_bmp.cpp b/modules/imgcodecs/src/grfmt_bmp.cpp index 91ef23cc3f..e69a93c78b 100644 --- a/modules/imgcodecs/src/grfmt_bmp.cpp +++ b/modules/imgcodecs/src/grfmt_bmp.cpp @@ -635,38 +635,40 @@ bool BmpEncoder::write( const Mat& img, const std::vector& ) m_buf->reserve( alignSize(fileSize + 16, 256) ); // write signature 'BM' - strm.putBytes( fmtSignBmp, (int)strlen(fmtSignBmp) ); + CHECK_WRITE(strm.putBytes( fmtSignBmp, (int)strlen(fmtSignBmp) )); // write file header - strm.putDWord( validateToInt(fileSize) ); // file size - strm.putDWord( 0 ); - strm.putDWord( headerSize ); + CHECK_WRITE(strm.putDWord( validateToInt(fileSize) )); // file size + CHECK_WRITE(strm.putDWord( 0 )); + CHECK_WRITE(strm.putDWord( headerSize )); // write bitmap header - strm.putDWord( bitmapHeaderSize ); - strm.putDWord( width ); - strm.putDWord( height ); - strm.putWord( 1 ); - strm.putWord( channels << 3 ); - strm.putDWord( BMP_RGB ); - strm.putDWord( 0 ); - strm.putDWord( 0 ); - strm.putDWord( 0 ); - strm.putDWord( 0 ); - strm.putDWord( 0 ); + CHECK_WRITE(strm.putDWord( bitmapHeaderSize )); + CHECK_WRITE(strm.putDWord( width )); + CHECK_WRITE(strm.putDWord( height )); + CHECK_WRITE(strm.putWord( 1 )); + CHECK_WRITE(strm.putWord( channels << 3 )); + CHECK_WRITE(strm.putDWord( BMP_RGB )); + CHECK_WRITE(strm.putDWord( 0 )); + CHECK_WRITE(strm.putDWord( 0 )); + CHECK_WRITE(strm.putDWord( 0 )); + CHECK_WRITE(strm.putDWord( 0 )); + CHECK_WRITE(strm.putDWord( 0 )); if( channels == 1 ) { FillGrayPalette( palette, 8 ); - strm.putBytes( palette, sizeof(palette)); + CHECK_WRITE(strm.putBytes( palette, sizeof(palette))); } width *= channels; for( int y = height - 1; y >= 0; y-- ) { - strm.putBytes( img.ptr(y), width ); + CHECK_WRITE(strm.putBytes( img.ptr(y), width )); if( fileStep > width ) - strm.putBytes( zeropad, fileStep - width ); + { + CHECK_WRITE(strm.putBytes( zeropad, fileStep - width )); + } } strm.close(); diff --git a/modules/imgcodecs/src/grfmt_pfm.cpp b/modules/imgcodecs/src/grfmt_pfm.cpp index b213d18fde..61cab06714 100644 --- a/modules/imgcodecs/src/grfmt_pfm.cpp +++ b/modules/imgcodecs/src/grfmt_pfm.cpp @@ -64,11 +64,11 @@ T read_number(cv::RLByteStream& strm) return atoT(str); } -template void write_anything(cv::WLByteStream& strm, const T& t) +template bool write_anything(cv::WLByteStream& strm, const T& t) { std::ostringstream ss; ss << t; - strm.putBytes(ss.str().c_str(), static_cast(ss.str().size())); + return strm.putBytes(ss.str().c_str(), static_cast(ss.str().size())); } } @@ -206,33 +206,33 @@ bool PFMEncoder::write(const Mat& img, const std::vector& params) } Mat float_img; - strm.putByte('P'); + CHECK_WRITE(strm.putByte('P')); switch (img.channels()) { case 1: - strm.putByte('f'); + CHECK_WRITE(strm.putByte('f')); img.convertTo(float_img, CV_32FC1); break; case 3: - strm.putByte('F'); + CHECK_WRITE(strm.putByte('F')); img.convertTo(float_img, CV_32FC3); break; default: CV_Error(Error::StsBadArg, "Expected 1 or 3 channel image."); } - strm.putByte('\n'); + CHECK_WRITE(strm.putByte('\n')); - write_anything(strm, float_img.cols); - strm.putByte(' '); - write_anything(strm, float_img.rows); - strm.putByte('\n'); + CHECK_WRITE(write_anything(strm, float_img.cols)); + CHECK_WRITE(strm.putByte(' ')); + CHECK_WRITE(write_anything(strm, float_img.rows)); + CHECK_WRITE(strm.putByte('\n')); #ifdef WORDS_BIGENDIAN - write_anything(strm, 1.0); + CHECK_WRITE(write_anything(strm, 1.0)); #else - write_anything(strm, -1.0); + CHECK_WRITE(write_anything(strm, -1.0)); #endif - strm.putByte('\n'); + CHECK_WRITE(strm.putByte('\n')); // Comments are not officially supported in this file format. // write_anything(strm, "# Generated by OpenCV " CV_VERSION "\n"); @@ -248,17 +248,15 @@ bool PFMEncoder::write(const Mat& img, const std::vector& params) rgb_row[x*3+1] = bgr_row[x*3+1]; rgb_row[x*3+2] = bgr_row[x*3+0]; } - strm.putBytes( reinterpret_cast(rgb_row.data()), - static_cast(sizeof(float) * row_size) ); + CHECK_WRITE(strm.putBytes( reinterpret_cast(rgb_row.data()), + static_cast(sizeof(float) * row_size) )); } else if (float_img.channels() == 1) { - strm.putBytes(float_img.ptr(y), sizeof(float) * float_img.cols); + CHECK_WRITE(strm.putBytes(float_img.ptr(y), sizeof(float) * float_img.cols)); } } return true; } - } - #endif // HAVE_IMGCODEC_PFM diff --git a/modules/imgcodecs/src/grfmt_pxm.cpp b/modules/imgcodecs/src/grfmt_pxm.cpp index d2ce60c743..20c815e833 100644 --- a/modules/imgcodecs/src/grfmt_pxm.cpp +++ b/modules/imgcodecs/src/grfmt_pxm.cpp @@ -479,7 +479,7 @@ bool PxMEncoder::write(const Mat& img, const std::vector& params) header_sz += sz; } - strm.putBytes(buffer, header_sz); + CHECK_WRITE(strm.putBytes(buffer, header_sz)); for( y = 0; y < height; y++ ) { @@ -512,7 +512,7 @@ bool PxMEncoder::write(const Mat& img, const std::vector& params) { *ptr++ = byte; } - strm.putBytes(buffer, (int)(ptr - buffer)); + CHECK_WRITE(strm.putBytes(buffer, (int)(ptr - buffer))); continue; } @@ -539,7 +539,7 @@ bool PxMEncoder::write(const Mat& img, const std::vector& params) } } - strm.putBytes( (channels > 1 || depth > 8) ? buffer : (const char*)data, fileStep); + CHECK_WRITE(strm.putBytes( (channels > 1 || depth > 8) ? buffer : (const char*)data, fileStep)); } else { @@ -610,7 +610,7 @@ bool PxMEncoder::write(const Mat& img, const std::vector& params) *ptr++ = '\n'; - strm.putBytes( buffer, (int)(ptr - buffer) ); + CHECK_WRITE(strm.putBytes( buffer, (int)(ptr - buffer) )); } } diff --git a/modules/imgcodecs/src/grfmt_sunras.cpp b/modules/imgcodecs/src/grfmt_sunras.cpp index 798f295376..852e735477 100644 --- a/modules/imgcodecs/src/grfmt_sunras.cpp +++ b/modules/imgcodecs/src/grfmt_sunras.cpp @@ -410,17 +410,17 @@ bool SunRasterEncoder::write( const Mat& img, const std::vector& ) if( strm.open(m_filename) ) { - strm.putBytes( fmtSignSunRas, (int)strlen(fmtSignSunRas) ); - strm.putDWord( width ); - strm.putDWord( height ); - strm.putDWord( channels*8 ); - strm.putDWord( fileStep*height ); - strm.putDWord( RAS_STANDARD ); - strm.putDWord( RMT_NONE ); - strm.putDWord( 0 ); + CHECK_WRITE(strm.putBytes( fmtSignSunRas, (int)strlen(fmtSignSunRas) )); + CHECK_WRITE(strm.putDWord( width )); + CHECK_WRITE(strm.putDWord( height )); + CHECK_WRITE(strm.putDWord( channels*8 )); + CHECK_WRITE(strm.putDWord( fileStep*height )); + CHECK_WRITE(strm.putDWord( RAS_STANDARD )); + CHECK_WRITE(strm.putDWord( RMT_NONE )); + CHECK_WRITE(strm.putDWord( 0 )); for( y = 0; y < height; y++ ) - strm.putBytes( img.ptr(y), fileStep ); + CHECK_WRITE(strm.putBytes( img.ptr(y), fileStep )); strm.close(); result = true; diff --git a/modules/imgcodecs/src/grfmt_tiff.cpp b/modules/imgcodecs/src/grfmt_tiff.cpp index f68a6e5c0d..e2184663aa 100644 --- a/modules/imgcodecs/src/grfmt_tiff.cpp +++ b/modules/imgcodecs/src/grfmt_tiff.cpp @@ -1100,16 +1100,6 @@ bool TiffEncoder::isFormatSupported( int depth ) const return depth == CV_8U || depth == CV_8S || depth == CV_16U || depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F; } -void TiffEncoder::writeTag( WLByteStream& strm, TiffTag tag, - TiffFieldType fieldType, - int count, int value ) -{ - strm.putWord( tag ); - strm.putWord( fieldType ); - strm.putDWord( count ); - strm.putDWord( value ); -} - class TiffEncoderBufHelper { public: diff --git a/modules/imgcodecs/src/grfmt_tiff.hpp b/modules/imgcodecs/src/grfmt_tiff.hpp index ee5bcb7018..0d1f511372 100644 --- a/modules/imgcodecs/src/grfmt_tiff.hpp +++ b/modules/imgcodecs/src/grfmt_tiff.hpp @@ -132,10 +132,6 @@ public: ImageEncoder newEncoder() const CV_OVERRIDE; protected: - void writeTag( WLByteStream& strm, TiffTag tag, - TiffFieldType fieldType, - int count, int value ); - bool writeLibTiff( const std::vector& img_vec, const std::vector& params ); bool write_32FC3_SGILOG(const Mat& img, void* tif);