继续opencv源码的研读,这里还是imread函数的跟进,昨天遇到了ImageDecoder这个类,这个类其实就是一个图像数据的解析类。且看下面的源代码:
class BaseImageDecoder //这就是我们要找的ImageDecoder类
{
public:
BaseImageDecoder();
virtual ~BaseImageDecoder() {};
int width() const { return m_width; };
int height() const { return m_height; };
int type() const { return m_type; };
virtual bool setSource( const string& filename );
virtual bool setSource( const Mat& buf );
virtual bool readHeader() = 0;
virtual bool readData( Mat& img ) = 0;
virtual size_t signatureLength() const;//(1)
virtual bool checkSignature( const string& signature ) const;
virtual ImageDecoder newDecoder() const;
protected:
int m_width; // width of the image ( filled by readHeader )
int m_height; // height of the image ( filled by readHeader )
int m_type;
string m_filename;
string m_signature;//(2)
Mat m_buf;
bool m_buf_supported;
};
下面定义了一些类型,
typedef Ptr<BaseImageDecoder> ImageDecoder; //这里typedef了一个类型ImageDecoder,这个最原始的类型为Ptr,猜想是一个指针,但是在源代码中没能找到其声明和定义的地方。但这不妨碍源码的阅读。
在findDecoder中用到了:static vector<ImageDecoder> decoders;
且在代码中有:decoders[i]->signatureLength();的调用,且可以看到(1)处就有这个函数。
size_t BaseImageDecoder::signatureLength() const
{
return m_signature.size();
}
上面这个函数其实返回的就是其保存的图像签名(signature)(2)。
bool BaseImageDecoder::checkSignature( const string& signature ) const
{
size_t len = signatureLength();
return signature.size() >= len && memcmp( signature.c_str(), m_signature.c_str(), len ) == 0;
}
ImageDecoder BaseImageDecoder::newDecoder() const
{
return ImageDecoder();//这里其实就是一个直接的调用了一个构造函数
}
BaseImageDecoder::BaseImageDecoder()
{
m_width = m_height = 0;
m_type = -1;
m_buf_supported = false;
}
这里看到的只是一个Base类,那么要真真的执行就是涉及到特定的图像类别了。
这里不看别的,就看一个bmp类型的吧:
class BmpDecoder : public BaseImageDecoder
{
public:
BmpDecoder();
~BmpDecoder();
bool readData( Mat& img );//很明显这是读取数据
bool readHeader();
void close();
ImageDecoder newDecoder() const;//这里重新的给了一个声明,表明在调用的时候调用的是子类的东西。
protected:
RLByteStream m_strm;
PaletteEntry m_palette[256];//调试版(palette)
int m_origin;
int m_bpp;
int m_offset;
BmpCompression m_rle_code;
/*压缩的格式
enum BmpCompression
{
BMP_RGB = 0,
BMP_RLE8 = 1,
BMP_RLE4 = 2,
BMP_BITFIELDS = 3
};
*/
};
bmpDecoder类里