源码解析: Imread函数

来源:互联网 发布:淘宝阿里旺旺买家版 编辑:程序博客网 时间:2024/06/05 11:34

源码解析: Imread函数 

 

i  mread()函数

 声明:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. Mat imread(const string& filename, int flags);  

这很标准的写法,传入一个string类型的常量引用。

定义: 

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. Mat imread(const string& filename, int flags)  
  2. {  
  3.     Mat img; //创建一个变量  
  4.     imread_(filename,flags,LOAD_MAT,&img);  
  5.     return img;  
  6. }  

其中imread_()中&img用的是地址符号,为什么呢?当然是为了改变其里面的数据了。imread( )函数是就这么几行么?这么几行能干什么呢?其实它把所有的事情交给了imread_()函数。所以,我们进一步分析imread_()函数。

imread_()函数

声明:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. static void* imread_(const string& filename, int flags, int hdrtype, Mat* mat=0 );  

其中这个函数返回的是一个空指针,其实在上面,这个返回值时没有用到的。 filename:文件地址 flags:标志,读取什么样(灰度,彩色)图像hdrtype:传入的为载入什么类型(enum {LOAD_CVMAT=0,LOAD_IMAGE=1, LOAD_MAT=2 };这三个中的一个。) Mat :保存图像的Mat对象了。

定义:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. static void* imread_(const string& filename, int flags, int hdrtype, Mat* mat=0)  
  2. {  
  3.     IplImage* image = 0;  
  4.     CvMat *matrix = 0;  
  5.     Mat temp, *data = &temp;  
  6.   
  7.     ImageDecoder decoder = findDecoder(filename);//这个是解析图像的后缀名的,用来决定读取特定图像的数据,所有的事情都是它干了。  
  8.     if( decoder.empty() )  
  9.         return 0;  
  10.     decoder->setSource(filename);  
  11.     if( !decoder->readHeader() )//读取图像的头部信息  
  12.         return 0;  
  13.   
  14.     CvSize size; //读取图像的大小  
  15.     size.width = decoder->width();  
  16.     size.height = decoder->height();  
  17.   
  18.     int type = decoder->type();//读取类型?  
  19.     if( flags != -1 )  
  20.     {         //决定什么样的类型  
  21.         if( (flags & CV_LOAD_IMAGE_ANYDEPTH) == 0 )  
  22.             type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));  
  23.   
  24.         if( (flags & CV_LOAD_IMAGE_COLOR) != 0 ||  
  25.            ((flags & CV_LOAD_IMAGE_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1) )  
  26.             type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3);//彩色  
  27.         else  
  28.             type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);//灰度  
  29.     }  
  30.   
  31.     if( hdrtype == LOAD_CVMAT || hdrtype == LOAD_MAT )  
  32.     {  
  33.         if( hdrtype == LOAD_CVMAT )  
  34.         {  
  35.             matrix = cvCreateMat( size.height, size.width, type );  
  36.             temp = cvarrToMat(matrix); //创建一个空的,即还没有图像数据的对象。  
  37.         }  
  38.         else  
  39.         {  
  40.             mat->create( size.height, size.width, type );  
  41.             data = mat;  
  42.         }  
  43.     }  
  44.     else//就是传入的类型都为IplImage*类型的  
  45.     {  
  46.         image = cvCreateImage( size, cvIplDepth(type), CV_MAT_CN(type) );  
  47.         temp = cvarrToMat(image);  
  48.     }  
  49.   
  50.     if(!decoder->readData(*data))//读取数据,这里应该是复制数据,想一想这个是要懂硬盘上去读取数据的。  
  51.     {//失败  
  52.         cvReleaseImage(&image);  
  53.         cvReleaseMat(&matrix);//c风格的释放  
  54.         if( mat )  
  55.             mat->release();//c++风格的释放  
  56.         return 0;  
  57.     }  
  58.   
  59.     return hdrtype == LOAD_CVMAT ? (void*)matrix :  
  60.         hdrtype == LOAD_IMAGE ? (void*)image : (void*)mat;//最后返回c类型的图像指针,这个是为了考虑c风格的  
  61. }  

上面看似不长啊,可这个怎么能干那么多的事情呢?那么就一步步的来分析吧。

这个看了半天,是不是没有什么实质性的东西?一个到底怎么读图还没完全了解吧。全都封装了起来(decoder),你看不到所有的细节,而只是一个大概的流程。这个流程不是自己都知道了么?

不管怎么样,我不想关注这个图是怎么解析的,只看这函数怎么把数据给读进了Mat中,先保持这个目标不变:

首先:传入了一个Mat类型的变量,这个变量是传了地址的,也就是会改变这个mat类型变量。Mat在构造函数中开始会构造什么呢?尤其是默认构造函数?其实他什么也没有构造,因为什么都不知道。

其次:Mat类型需要记录图像的哪些数据呢?一个是头:图像是灰度或彩色(这里姑且只考虑这两种),一个图像数据的大小(图像的宽与高);一个数据体:二维数组或是一维数组。

最后:从decoder中读入data数据。当然这里会牵涉到图像解码过程的(这个如果特别感兴趣就看看了,否则不用了)。

在第一篇处,我们只是在最表层的上面操作函数,当别人问我们时,我们其实什么也不知道的。就知道,imread是读取函数了,然后掉用其它的函数的乐乐。当然,上面我们可以好好学习人家为什么要这样做了!这里,看一个函数finddecoder()。这个函数主要是获取decoder对象,从而决定读取什么样后缀名的图像(jpg,bmp等等)

findDecoder()函数

声明:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. ImageDecoder findDecoder( const string& filename );//在highgui/loadsave.cpp中  
  2. ImageDecoder findDecoder( const Mat& buf );  
这个是一个函数的重载了,在第一篇,即imread函数中调用的是第一个,这里就跟进第一个。

定义:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. ImageDecoder findDecoder( const string& filename )  
  2. {  
  3.     size_t i, maxlen = 0;  
  4.     for( i = 0; i < decoders.size(); i++ )//这里第一个decoders是什么呢?在文件中有这样的一个定义:static vector<ImageDecoder> decoders;好家伙,原来是一个向量,这里第一问,为什么要是一个向量,而且还是全局静态变量,就是说整个程序运行期间它都存在。其只初始化一遍。  
  5.     {  
  6.         size_t len = decoders[i]->signatureLength();//这一个循环是寻找第一个数据点保存的数据:signature。从这里可以看出,其实后缀名在这里没有什么用处,文件本身是保存了这个类型值的。  
  7.         maxlen = std::max(maxlen, len);//读取数据长度为一个最大的。  
  8.     }  
  9.   
  10.     FILE* f= fopen( filename.c_str(), "rb" );//熟悉的c函数,读取文件。哈哈,从这个可以看到,所有的文件都可以有FILE来读取的。  
  11.     if( !f )  
  12.         return ImageDecoder();//没有读取成功,返回一个空的decoder。处理错误的能力。  
  13.     string signature(maxlen, ' ');  
  14.   
  15.   maxlen = fread( &signature[0], 1, maxlen, f );//从文件中读取signature数据,这里是用了string,且是按字节读取。string底层用了什么结构呢?string[0]返回的是一个什么值呢?这有待查询。  
  16.   
  17. /*这里是一个试验: 
  18.  
  19.     int maxlen = 10 ; 
  20.     string sig(maxlen,' '); 
  21.     cout<<&sig<<endl; 
  22.     cout<<((int*)&sig[0])<<endl; 
  23.  
  24.    cout<<((int*)&sig[1])<<endl; 
  25.  
  26.   从其中可以看出两个量的值是不同的: 
  27.  
  28. 0x22ff40 
  29. 0x3e3cbc   //这里和后面的数据相差一个字节,代表这是一个char类型的 
  30. 0x3e3cbd 
  31.  
  32. */  
  33.     fclose(f);  
  34.     signature = signature.substr(0, maxlen);  
  35.   
  36.     for( i = 0; i < decoders.size(); i++ )  
  37.     {  
  38.         if( decoders[i]->checkSignature(signature) )//检测读取出来的数据是否与保存的数据signature一样,一样就代表是这个类型了。  
  39.             return decoders[i]->newDecoder();//创建这个类型的decoder变量。  
  40.     }  
  41.   
  42.     return ImageDecoder();  
  43. }  

下面是decoders数据内容的来源:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. struct ImageCodecInitializer  
  2. {  
  3.     ImageCodecInitializer( )  
  4.     {  
  5.         decoders.push_back(new BmpDecoder);  
  6.         encoders.push_back(new BmpEncoder);  
  7.     #ifdef HAVE_JPEG  
  8.         decoders.push_back(new JpegDecoder);  
  9.         encoders.push_back(new JpegEncoder);  
  10.     #endif  
  11.         decoders.push_back(new SunRasterDecoder);  
  12.         encoders.push_back(new SunRasterEncoder);  
  13.         decoders.push_back(new PxMDecoder);  
  14.         encoders.push_back(new PxMEncoder);  
  15.     #ifdef HAVE_TIFF  
  16.         decoders.push_back(new TiffDecoder);  
  17.     #endif  
  18.         encoders.push_back(new TiffEncoder);  
  19.     #ifdef HAVE_PNG  
  20.         decoders.push_back(new PngDecoder);  
  21.         encoders.push_back(new PngEncoder);  
  22.     #endif  
  23.     #ifdef HAVE_JASPER  
  24.         decoders.push_back(new Jpeg2KDecoder);  
  25.         encoders.push_back(new Jpeg2KEncoder);  
  26.     #endif  
  27.     #ifdef HAVE_OPENEXR  
  28.         decoders.push_back(new ExrDecoder);  
  29.         encoders.push_back(new ExrEncoder);  
  30.     #endif  
  31.     // because it is a generic image I/O API, supporting many formats,  
  32.     // it should be last in the list.  
  33.     #ifdef HAVE_IMAGEIO  
  34.         decoders.push_back(new ImageIODecoder);  
  35.         encoders.push_back(new ImageIOEncoder);  
  36.     #endif  
  37.     }  
  38. };  

static ImageCodecInitializer initialize_codecs; //这里直接的给定了decoders的内容。

这样读取图像数据又清晰了一步,首先是我们会首先保存好要解析的图像格式,即支持什么类型的图像。然后第一步是取读取保存在第一个数据点上的signature数据,然后再去读取下面的数据。所以,要很清楚的了解图像的头。

ImageDecoder类

ImageDecoder这个类,这个类其实就是一个图像数据的解析类。且看下面的

源代码:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. class BaseImageDecoder //这就是我们要找的ImageDecoder类  
  2. {  
  3. public:  
  4.     BaseImageDecoder();  
  5.     virtual ~BaseImageDecoder() {};  
  6.   
  7.     int width() const { return m_width; };  
  8.     int height() const { return m_height; };  
  9.     int type() const { return m_type; };  
  10.   
  11.     virtual bool setSource( const string& filename );  
  12.     virtual bool setSource( const Mat& buf );  
  13.     virtual bool readHeader() = 0;  
  14.     virtual bool readData( Mat& img ) = 0;  
  15.   
  16.     virtual size_t signatureLength() const;//(1)  
  17.     virtual bool checkSignature( const string& signature ) const;  
  18.     virtual ImageDecoder newDecoder() const;  
  19.   
  20. protected:  
  21.     int  m_width;  // width  of the image ( filled by readHeader )  
  22.     int  m_height; // height of the image ( filled by readHeader )  
  23.     int  m_type;  
  24.     string m_filename;  
  25.     string m_signature;//(2)  
  26.     Mat m_buf;  
  27.     bool m_buf_supported;  
  28. };  
下面定义了一些类型,

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. typedef Ptr<BaseImageDecoder> ImageDecoder; //  
这里typedef了一个类型ImageDecoder,这个最原始的类型为Ptr,猜想是一个指针,但是在源代码中没能找到其声明和定义的地方。但这不妨碍源码的阅读。

在findDecoder中用到了:static vector<ImageDecoder> decoders;

且在代码中有:decoders[i]->signatureLength();的调用,且可以看到(1)处就有这个函数。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. size_t BaseImageDecoder::signatureLength() const  
  2. {  
  3.     return m_signature.size();  
  4. }  
上面这个函数其实返回的就是其保存的图像签名(signature)(2)

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. bool BaseImageDecoder::checkSignature(const string& signature) const  
  2. {  
  3.     size_t len = signatureLength();  
  4.     return signature.size()>= len&&memcmp(signature.c_str(),m_signature.c_str(),len)==0;  
  5. }  
  6. ImageDecoder BaseImageDecoder::newDecoder() const  
  7. {  
  8.     return ImageDecoder();//这里其实就是一个直接的调用了一个构造函数  
  9. }  
  10. BaseImageDecoder::BaseImageDecoder()  
  11. {  
  12.     m_width = m_height = 0;  
  13.     m_type = -1;  
  14.     m_buf_supported = false;  
  15. }   
这里看到的只是一个Base类,那么要真真的执行就是涉及到特定的图像类别了。

这里不看别的,就看一个bmp类型的吧:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. class BmpDecoder : public BaseImageDecoder  
  2. {  
  3. public:  
  4.     BmpDecoder();  
  5.     ~BmpDecoder();  
  6.      
  7.     bool  readData( Mat& img );//很明显这是读取数据  
  8.     bool  readHeader();  
  9.     void  close();  
  10.     ImageDecoder newDecoder() const;//这里重新的给了一个声明,表明在调用的时候调用的是子类的东西。  
  11.   
  12. protected:  
  13.     RLByteStream    m_strm;  
  14.     PaletteEntry    m_palette[256];//调试版(palette)  
  15.     int             m_origin;  
  16.     int             m_bpp;  
  17.     int             m_offset;  
  18.     BmpCompression  m_rle_code;  
  19.   
  20. /*压缩的格式 
  21. enum BmpCompression 
  22. { 
  23.     BMP_RGB = 0, 
  24.     BMP_RLE8 = 1, 
  25.     BMP_RLE4 = 2, 
  26.     BMP_BITFIELDS = 3 
  27. }; 
  28. */  
  29. };  
  30.   
  31. bmpDecoder类里面的东西很多,这里简要的给看看:  
  32. ImageDecoder BmpDecoder::newDecoder() const  
  33. {  
  34.     return new BmpDecoder;  
  35. }  
  36.   
  37. BmpDecoder::BmpDecoder()  
  38. {  
  39.     m_signature = fmtSignBmp;//static const char* fmtSignBmp = "BM"; 设定了自己标签名  
  40.     m_offset = -1;    
  41.    m_buf_supported = true;//buf设定为true,表示可以读取数据  
  42. }  
bmpDecoder类里面的东西很多,这里简要的给看看:

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. ImageDecoder BmpDecoder::newDecoder() const  
  2. {  
  3.     return new BmpDecoder;  
  4. }  
  5.   
  6. BmpDecoder::BmpDecoder()  
  7. {  
  8.     m_signature = fmtSignBmp;//static const char* fmtSignBmp = "BM"; 设定了自己标签名  
  9.     m_offset = -1;    
  10.    m_buf_supported = true;//buf设定为true,表示可以读取数据  
  11. }  
这里就完全的看到了底层的代码了。这就需要完全的理解bmp图像的保存格式了。还没完全的了解bmp,暂且把这个代码贴在这吧。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. bool  BmpDecoder::readData(Mat& img){  
  2.     uchar* data = img.data;  
  3.     int step = (int)img.step;  
  4.     bool color = img.channels() > 1;  
  5.     uchar  gray_palette[256];  
  6.     bool   result = false;  
  7.     int  src_pitch = ((m_width*(m_bpp != 15 ? m_bpp : 16) + 7)/8 + 3) & -4;  
  8.     int  nch = color ? 3 : 1;  
  9.     int  y, width3 = m_width*nch;  
  10.   
  11.     if( m_offset < 0 || !m_strm.isOpened())  
  12.         return false;  
  13.   
  14.     if( m_origin == IPL_ORIGIN_BL ){  
  15.         data += (m_height - 1)*step;  
  16.         step = -step;  
  17.     }  
  18.   
  19.     AutoBuffer<uchar> _src, _bgr;  
  20.     _src.allocate(src_pitch + 32);  
  21.   
  22.     if(!color){  
  23.         if(m_bpp <= 8){  
  24.             CvtPaletteToGray( m_palette, gray_palette, 1 << m_bpp );  
  25.         }  
  26.         _bgr.allocate(m_width*3 + 32);  
  27.     }  
  28.     uchar *src = _src, *bgr = _bgr;  
  29.   
  30.     try{  
  31.         m_strm.setPos(m_offset);  
  32.         switch(m_bpp){  
  33.         /************************* 1 BPP ************************/  
  34.         case 1:  
  35.             for( y = 0; y < m_height; y++, data += step){  
  36.                 m_strm.getBytes( src, src_pitch );  
  37.                 FillColorRow1( color ? data : bgr, src, m_width, m_palette );  
  38.                 if( !color )  
  39.                     icvCvt_BGR2Gray_8u_C3C1R( bgr, 0, data, 0, cvSize(m_width,1));  
  40.             }  
  41.             result = true;  
  42.             break;  
  43.   
  44.         /************************* 4 BPP ************************/  
  45.         case 4:  
  46.             if( m_rle_code == BMP_RGB){  
  47.                 for( y = 0; y < m_height; y++, data += step )  
  48.                 {  
  49.                     m_strm.getBytes( src, src_pitch );  
  50.                     if( color )  
  51.                         FillColorRow4( data, src, m_width, m_palette );  
  52.                     else  
  53.                         FillGrayRow4( data, src, m_width, gray_palette );  
  54.                 }  
  55.                 result = true;  
  56.             }  
  57.             else if( m_rle_code == BMP_RLE4 ) // rle4 compression  
  58.             {  
  59.                 uchar* line_end = data + width3;  
  60.                 y = 0;  
  61.   
  62.                 for(;;)  
  63.                 {  
  64.                     int code = m_strm.getWord();  
  65.                     int len = code & 255;  
  66.                     code >>= 8;  
  67.                     if( len != 0 ) // encoded mode  
  68.                     {  
  69.                         PaletteEntry clr[2];  
  70.                         uchar gray_clr[2];  
  71.                         int t = 0;  
  72.   
  73.                         clr[0] = m_palette[code >> 4];  
  74.                         clr[1] = m_palette[code & 15];  
  75.                         gray_clr[0] = gray_palette[code >> 4];  
  76.                         gray_clr[1] = gray_palette[code & 15];  
  77.   
  78.                         uchar* end = data + len*nch;  
  79.                         if( end > line_end ) goto decode_rle4_bad;  
  80.                         do  
  81.                         {  
  82.                             if( color )  
  83.                                 WRITE_PIX( data, clr[t] );  
  84.                             else  
  85.                                 *data = gray_clr[t];  
  86.                             t ^= 1;  
  87.                         }  
  88.                         while( (data += nch) < end );  
  89.                     }  
  90.                     else if( code > 2 ) // absolute mode  
  91.                     {  
  92.                         if( data + code*nch > line_end ) goto decode_rle4_bad;  
  93.                         m_strm.getBytes( src, (((code + 1)>>1) + 1) & -2 );  
  94.                         if( color )  
  95.                             data = FillColorRow4( data, src, code, m_palette );  
  96.                         else  
  97.                             data = FillGrayRow4( data, src, code, gray_palette );  
  98.                     }  
  99.                     else  
  100.                     {  
  101.                         int x_shift3 = (int)(line_end - data);  
  102.                         int y_shift = m_height - y;  
  103.   
  104.                         if( code == 2 )  
  105.                         {  
  106.                             x_shift3 = m_strm.getByte()*nch;  
  107.                             y_shift = m_strm.getByte();  
  108.                         }  
  109.   
  110.                         len = x_shift3 + ((y_shift * width3) & ((code == 0) - 1));  
  111.   
  112.                         if( color )  
  113.                             data = FillUniColor( data, line_end, step, width3,  
  114.                                                  y, m_height, x_shift3,  
  115.                                                  m_palette[0] );  
  116.                         else  
  117.                             data = FillUniGray( data, line_end, step, width3,  
  118.                                                 y, m_height, x_shift3,  
  119.                                                 gray_palette[0] );  
  120.   
  121.                         if( y >= m_height )  
  122.                             break;  
  123.                     }  
  124.                 }  
  125.                 result = true;  
  126.             decode_rle4_bad: ;  
  127.             }  
  128.             break;  
  129.   
  130.         /************************* 8 BPP ************************/  
  131.         case 8:  
  132.             if( m_rle_code == BMP_RGB )  
  133.             {  
  134.                 for( y = 0; y < m_height; y++, data += step )  
  135.                 {  
  136.                     m_strm.getBytes( src, src_pitch );  
  137.                     if( color )  
  138.                         FillColorRow8( data, src, m_width, m_palette );  
  139.                     else  
  140.                         FillGrayRow8( data, src, m_width, gray_palette );  
  141.                 }  
  142.                 result = true;  
  143.             }  
  144.             else if( m_rle_code == BMP_RLE8 ) // rle8 compression  
  145.             {  
  146.                 uchar* line_end = data + width3;  
  147.                 int line_end_flag = 0;  
  148.                 y = 0;  
  149.   
  150.                 for(;;)  
  151.                 {  
  152.                     int code = m_strm.getWord();  
  153.                     int len = code & 255;  
  154.                     code >>= 8;  
  155.                     if( len != 0 ) // encoded mode  
  156.                     {  
  157.                         int prev_y = y;  
  158.                         len *= nch;  
  159.   
  160.                         if( data + len > line_end )  
  161.                             goto decode_rle8_bad;  
  162.   
  163.                         if( color )  
  164.                             data = FillUniColor( data, line_end, step, width3,  
  165.                                                  y, m_height, len,  
  166.                                                  m_palette[code] );  
  167.                         else  
  168.                             data = FillUniGray( data, line_end, step, width3,  
  169.                                                 y, m_height, len,  
  170.                                                 gray_palette[code] );  
  171.   
  172.                         line_end_flag = y - prev_y;  
  173.                     }  
  174.                     else if( code > 2 ) // absolute mode  
  175.                     {  
  176.                         int prev_y = y;  
  177.                         int code3 = code*nch;  
  178.   
  179.                         if( data + code3 > line_end )  
  180.                             goto decode_rle8_bad;  
  181.                         m_strm.getBytes( src, (code + 1) & -2 );  
  182.                         if( color )  
  183.                             data = FillColorRow8( data, src, code, m_palette );  
  184.                         else  
  185.                             data = FillGrayRow8( data, src, code, gray_palette );  
  186.   
  187.                         line_end_flag = y - prev_y;  
  188.                     }  
  189.                     else  
  190.                     {  
  191.                         int x_shift3 = (int)(line_end - data);  
  192.                         int y_shift = m_height - y;  
  193.   
  194.                         if( code || !line_end_flag || x_shift3 < width3 )  
  195.                         {  
  196.                             if( code == 2 )  
  197.                             {  
  198.                                 x_shift3 = m_strm.getByte()*nch;  
  199.                                 y_shift = m_strm.getByte();  
  200.                             }  
  201.   
  202.                             x_shift3 += (y_shift * width3) & ((code == 0) - 1);  
  203.   
  204.                             if( y >= m_height )  
  205.                                 break;  
  206.   
  207.                             if( color )  
  208.                                 data = FillUniColor( data, line_end, step, width3,  
  209.                                                      y, m_height, x_shift3,  
  210.                                                      m_palette[0] );  
  211.                             else  
  212.                                 data = FillUniGray( data, line_end, step, width3,  
  213.                                                     y, m_height, x_shift3,  
  214.                                                     gray_palette[0] );  
  215.   
  216.                             if( y >= m_height )  
  217.                                 break;  
  218.                         }  
  219.   
  220.                         line_end_flag = 0;  
  221.                     }  
  222.                 }  
  223.   
  224.                 result = true;  
  225.             decode_rle8_bad: ;  
  226.             }  
  227.             break;  
  228.         /************************* 15 BPP ************************/  
  229.         case 15:  
  230.             for( y = 0; y < m_height; y++, data += step )  
  231.             {  
  232.                 m_strm.getBytes( src, src_pitch );  
  233.                 if( !color )  
  234.                     icvCvt_BGR5552Gray_8u_C2C1R( src, 0, data, 0, cvSize(m_width,1) );  
  235.                 else  
  236.                     icvCvt_BGR5552BGR_8u_C2C3R( src, 0, data, 0, cvSize(m_width,1) );  
  237.             }  
  238.             result = true;  
  239.             break;  
  240.         /************************* 16 BPP ************************/  
  241.         case 16:  
  242.             for( y = 0; y < m_height; y++, data += step )  
  243.             {  
  244.                 m_strm.getBytes( src, src_pitch );  
  245.                 if( !color )  
  246.                     icvCvt_BGR5652Gray_8u_C2C1R( src, 0, data, 0, cvSize(m_width,1) );  
  247.                 else  
  248.                     icvCvt_BGR5652BGR_8u_C2C3R( src, 0, data, 0, cvSize(m_width,1) );  
  249.             }  
  250.             result = true;  
  251.             break;  
  252.         /************************* 24 BPP ************************/  
  253.         case 24:  
  254.             for( y = 0; y < m_height; y++, data += step )  
  255.             {  
  256.                 m_strm.getBytes( src, src_pitch );  
  257.                 if(!color)  
  258.                     icvCvt_BGR2Gray_8u_C3C1R( src, 0, data, 0, cvSize(m_width,1) );  
  259.                 else  
  260.                     memcpy( data, src, m_width*3 );  
  261.             }  
  262.             result = true;  
  263.             break;  
  264.         /************************* 32 BPP ************************/  
  265.         case 32:  
  266.             for( y = 0; y < m_height; y++, data += step )  
  267.             {  
  268.                 m_strm.getBytes( src, src_pitch );  
  269.   
  270.                 if( !color )  
  271.                     icvCvt_BGRA2Gray_8u_C4C1R( src, 0, data, 0, cvSize(m_width,1) );  
  272.                 else  
  273.                     icvCvt_BGRA2BGR_8u_C4C3R( src, 0, data, 0, cvSize(m_width,1) );  
  274.             }  
  275.             result = true;  
  276.             break;  
  277.         default:  
  278.             assert(0);  
  279.         }  
  280.     }  
  281.     catch(...)  
  282.     {  
  283.     }  
  284.   
  285.     return result;  
0 0
原创粉丝点击