diff --git a/modules/imgcodecs/src/grfmt_pam.cpp b/modules/imgcodecs/src/grfmt_pam.cpp index c1d59d291a..58b00c81ba 100644 --- a/modules/imgcodecs/src/grfmt_pam.cpp +++ b/modules/imgcodecs/src/grfmt_pam.cpp @@ -56,7 +56,7 @@ #include "utils.hpp" #include "grfmt_pam.hpp" -using namespace cv; +namespace cv { /* the PAM related fields */ #define MAX_PAM_HEADER_IDENITFIER_LENGTH 8 @@ -220,14 +220,14 @@ basic_conversion (void *src, const struct channel_layout *layout, int src_sampe_ } -static bool ReadPAMHeaderLine (cv::RLByteStream& strm, - PamHeaderFieldType &fieldtype, - char value[MAX_PAM_HEADER_VALUE_LENGTH+1]) +static +bool ReadPAMHeaderLine( + cv::RLByteStream& strm, + CV_OUT PamHeaderFieldType &fieldtype, + CV_OUT char value[MAX_PAM_HEADER_VALUE_LENGTH+1]) { - int code, pos; - bool ident_found = false; - uint i; - char ident[MAX_PAM_HEADER_IDENITFIER_LENGTH+1] = { 0 }; + int code; + char ident[MAX_PAM_HEADER_IDENITFIER_LENGTH+1] = {}; do { code = strm.getByte(); @@ -246,82 +246,95 @@ static bool ReadPAMHeaderLine (cv::RLByteStream& strm, return true; } - /* nul-ify buffers before writing to them */ - memset (ident, '\0', sizeof(char) * MAX_PAM_HEADER_IDENITFIER_LENGTH); - for (i=0; i= 0 && isspace(value[pos])) - value[pos--] = '\0'; + while (--pos >= 0 && isspace(value[pos])) + value[pos] = 0; return true; } -static bool ParseNumber (char *str, int *retval) +static int ParseInt(const char *str, int len) { - char *endptr; - long lval = strtol (str, &endptr, 0); - - if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) - || (errno != 0 && lval == 0)) { - return false; - } - if (endptr == str) { - return false; - } - - *retval = (int) lval; + CV_Assert(len > 0); - return true; + int pos = 0; + bool is_negative = false; + if (str[0] == '-') + { + is_negative = true; + pos++; + CV_Assert(isdigit(str[pos])); + } + uint64_t number = 0; + while (pos < len && isdigit(str[pos])) + { + char ch = str[pos]; + number = (number * 10) + (uint64_t)((int)ch - (int)'0'); + CV_Assert(number < INT_MAX); + pos++; + } + if (pos < len) + CV_Assert(str[pos] == 0); + return (is_negative) ? -(int)number : (int)number; } -namespace cv -{ + PAMDecoder::PAMDecoder() { @@ -357,21 +370,12 @@ ImageDecoder PAMDecoder::newDecoder() const return makePtr(); } -struct parsed_fields -{ - bool endhdr, height, width, depth, maxval; -}; - -#define HEADER_READ_CORRECT(pf) (pf.endhdr && pf.height && pf.width \ - && pf.depth && pf.maxval) - - -bool PAMDecoder::readHeader() +bool PAMDecoder::readHeader() { PamHeaderFieldType fieldtype = PAM_HEADER_NONE; char value[MAX_PAM_HEADER_VALUE_LENGTH+1]; int byte; - struct parsed_fields flds; + if( !m_buf.empty() ) { if( !m_strm.open(m_buf) ) @@ -379,6 +383,7 @@ bool PAMDecoder::readHeader() } else if( !m_strm.open( m_filename )) return false; + try { byte = m_strm.getByte(); @@ -393,70 +398,72 @@ bool PAMDecoder::readHeader() if (byte != '\n' && byte != '\r') throw RBS_BAD_HEADER; - uint i; - memset (&flds, 0x00, sizeof (struct parsed_fields)); + bool flds_endhdr = false, flds_height = false, flds_width = false, flds_depth = false, flds_maxval = false; + do { if (!ReadPAMHeaderLine(m_strm, fieldtype, value)) throw RBS_BAD_HEADER; - switch (fieldtype) { + switch (fieldtype) + { case PAM_HEADER_NONE: case PAM_HEADER_COMMENT: continue; case PAM_HEADER_ENDHDR: - flds.endhdr = true; + flds_endhdr = true; break; case PAM_HEADER_HEIGHT: - if (flds.height) - throw RBS_BAD_HEADER; - if (!ParseNumber (value, &m_height)) + if (flds_height) throw RBS_BAD_HEADER; - flds.height = true; + m_height = ParseInt(value, MAX_PAM_HEADER_VALUE_LENGTH); + flds_height = true; break; case PAM_HEADER_WIDTH: - if (flds.width) + if (flds_width) throw RBS_BAD_HEADER; - if (!ParseNumber (value, &m_width)) - throw RBS_BAD_HEADER; - flds.width = true; + m_width = ParseInt(value, MAX_PAM_HEADER_VALUE_LENGTH); + flds_width = true; break; case PAM_HEADER_DEPTH: - if (flds.depth) - throw RBS_BAD_HEADER; - if (!ParseNumber (value, &m_channels)) + if (flds_depth) throw RBS_BAD_HEADER; - flds.depth = true; + m_channels = ParseInt(value, MAX_PAM_HEADER_VALUE_LENGTH); + flds_depth = true; break; case PAM_HEADER_MAXVAL: - if (flds.maxval) - throw RBS_BAD_HEADER; - if (!ParseNumber (value, &m_maxval)) + if (flds_maxval) throw RBS_BAD_HEADER; + m_maxval = ParseInt(value, MAX_PAM_HEADER_VALUE_LENGTH); if ( m_maxval > 65535 ) throw RBS_BAD_HEADER; - if ( m_maxval > 255 ) { - m_sampledepth = CV_16U; - } - else - m_sampledepth = CV_8U; + m_sampledepth = (m_maxval > 255) ? CV_16U : CV_8U; if (m_maxval == 1) bit_mode = true; - flds.maxval = true; + flds_maxval = true; break; case PAM_HEADER_TUPLTYPE: - for (i=0; i> 8); @@ -589,7 +599,7 @@ bool PAMDecoder::readData( Mat& img ) } /* perform correct conversion based on format */ else if (fmt) { - funcout = false; + bool funcout = false; if (fmt->cvt_func) funcout = fmt->cvt_func (src, data, m_width, target_channels, img.depth()); @@ -608,13 +618,8 @@ bool PAMDecoder::readData( Mat& img ) } } } - - res = true; - } catch(...) - { } - - return res; + return true; }