⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grfmt_bmp.cpp

📁 OPENCV系列的
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                    else if( code > 2 ) // absolute mode
                    {
                        if( data + code*nch > line_end ) goto decode_rle4_bad;
                        m_strm.GetBytes( src, (((code + 1)>>1) + 1) & -2 );
                        if( color )
                            data = FillColorRow4( data, src, code, m_palette );
                        else
                            data = FillGrayRow4( data, src, code, gray_palette );
                    }
                    else
                    {
                        int x_shift3 = line_end - data;
                        int y_shift = m_height - y;

                        if( code == 2 )
                        {
                            x_shift3 = m_strm.GetByte()*nch;
                            y_shift = m_strm.GetByte();
                        }

                        len = x_shift3 + (y_shift * width3) & ((code == 0) - 1);

                        if( color )
                            data = FillUniColor( data, line_end, step, width3, 
                                                 y, m_height, x_shift3,
                                                 m_palette[0] );
                        else
                            data = FillUniGray( data, line_end, step, width3, 
                                                y, m_height, x_shift3,
                                                gray_palette[0] );

                        if( y >= m_height )
                            break;
                    }
                }

                result = true;
decode_rle4_bad: ;
            }
            break;

        /************************* 8 BPP ************************/
        case 8:
            if( m_rle_code == BMP_RGB )
            {
                for( y = 0; y < m_height; y++, data += step )
                {
                    m_strm.GetBytes( src, src_pitch );
                    if( color )
                        FillColorRow8( data, src, m_width, m_palette );
                    else
                        FillGrayRow8( data, src, m_width, gray_palette );
                }
                result = true;
            }
            else if( m_rle_code == BMP_RLE8 ) // rle8 compression
            {
                uchar* line_end = data + width3;
                int line_end_flag = 0;
                y = 0;

                for(;;)
                {
                    int code = m_strm.GetWord();
                    int len = code & 255;
                    code >>= 8;
                    if( len != 0 ) // encoded mode
                    {
                        int prev_y = y;
                        len *= nch;
                        
                        if( data + len > line_end )
                            goto decode_rle8_bad;

                        if( color )
                            data = FillUniColor( data, line_end, step, width3, 
                                                 y, m_height, len,
                                                 m_palette[code] );
                        else
                            data = FillUniGray( data, line_end, step, width3, 
                                                y, m_height, len,
                                                gray_palette[code] );

                        line_end_flag = y - prev_y;
                    }
                    else if( code > 2 ) // absolute mode
                    {
                        int prev_y = y;
                        int code3 = code*nch;
                        
                        if( data + code3 > line_end )
                            goto decode_rle8_bad;
                        m_strm.GetBytes( src, (code + 1) & -2 );
                        if( color )
                            data = FillColorRow8( data, src, code, m_palette );
                        else
                            data = FillGrayRow8( data, src, code, gray_palette );

                        line_end_flag = y - prev_y;
                    }
                    else
                    {
                        int x_shift3 = line_end - data;
                        int y_shift = m_height - y;
                        
                        if( code || !line_end_flag || x_shift3 < width3 )
                        {
                            if( code == 2 )
                            {
                                x_shift3 = m_strm.GetByte()*nch;
                                y_shift = m_strm.GetByte();
                            }

                            len = x_shift3 + ((y_shift * width3) & ((code == 0) - 1));

                            if( y >= m_height )
                                break;

                            if( color )
                                data = FillUniColor( data, line_end, step, width3, 
                                                     y, m_height, x_shift3,
                                                     m_palette[0] );
                            else
                                data = FillUniGray( data, line_end, step, width3, 
                                                    y, m_height, x_shift3,
                                                    gray_palette[0] );

                            if( y >= m_height )
                                break;
                        }

                        line_end_flag = 0;
                    }
                }

                result = true;
decode_rle8_bad: ;
            }
            break;
        /************************* 24 BPP ************************/
        case 24:
            for( y = 0; y < m_height; y++, data += step )
            {
                m_strm.GetBytes( color ? data : src, src_pitch );
                if( !color ) CvtBGRToGray( src, data, m_width );
            }
            result = true;
            break;
        /************************* 32 BPP ************************/
        case 32:
            for( y = 0; y < m_height; y++, data += step )
            {
                m_strm.GetBytes( src, src_pitch );

                if( color )
                    CvtBGRAToBGR( src, data, m_width );
                else
                    CvtBGRAToGray( src, data, m_width );
            }
            result = true;
            break;
        default:
            assert(0);
        }
    }
    catch( int )
    {
    }

    if( src != buffer ) delete src; 
    if( bgr != bgr_buffer ) delete bgr;
    return true;
}


//////////////////////////////////////////////////////////////////////////////////////////

GrFmtBmpWriter::GrFmtBmpWriter()
{
    m_description = fmtDescrBmp;
}


GrFmtBmpWriter::~GrFmtBmpWriter()
{
}


bool  GrFmtBmpWriter::WriteImage( const char* filename,
                                  const uchar* data, int step,
                                  int width, int height, bool isColor )
{
    bool result = false;
    int nch  = isColor ? 3 : 1;
    int fileStep = (width*nch + 3) & -4;

    assert( data && width > 0 && height > 0 && step >= fileStep);
    
    if( m_strm.Open( filename ) )
    {
        int  bitmapHeaderSize = 40;
        int  paletteSize = isColor ? 0 : 1024;
        int  headerSize = (14 /* fileheader */ + bitmapHeaderSize +
                           paletteSize + 3) & -4;
        int  i;
        PaletteEntry palette[256];
        
        // write signature 'BM'
        m_strm.PutBytes( fmtSignBmp, strlen(fmtSignBmp) );

        // write file header
        m_strm.PutDWord( fileStep*height + headerSize ); // file size
        m_strm.PutDWord( 0 );
        m_strm.PutDWord( headerSize );

        // write bitmap header
        m_strm.PutDWord( bitmapHeaderSize );
        m_strm.PutDWord( width );
        m_strm.PutDWord( height );
        m_strm.PutWord( 1 );
        m_strm.PutWord( nch << 3 );
        m_strm.PutDWord( BMP_RGB );
        m_strm.PutDWord( 0 );
        m_strm.PutDWord( 0 );
        m_strm.PutDWord( 0 );
        m_strm.PutDWord( 0 );
        m_strm.PutDWord( 0 );

        if( !isColor )
        {
            FillGrayPalette( palette, 8 );
            m_strm.PutBytes( palette, sizeof(palette));
        }

        // for alignment
        m_strm.PutWord(0); 
        
        data += step*(height - 1);
        for( i = height; i > 0; i--, data -= step )
            m_strm.PutBytes( data, step );

        m_strm.Close();
        result = true;
    }
    return result;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -