📄 grfmt_bmp.cpp
字号:
WRITE_PIX( data, clr[t] );
else
*data = gray_clr[t];
t ^= 1;
}
while( (data += nch) < end );
}
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 = (int)(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 = (int)(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();
}
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;
/************************* 15 BPP ************************/
case 15:
for( y = 0; y < m_height; y++, data += step )
{
m_strm.GetBytes( src, src_pitch );
if( !color )
icvCvt_BGR5552Gray_8u_C2C1R( src, 0, data, 0, cvSize(m_width,1) );
else
icvCvt_BGR5552BGR_8u_C2C3R( src, 0, data, 0, cvSize(m_width,1) );
}
result = true;
break;
/************************* 16 BPP ************************/
case 16:
for( y = 0; y < m_height; y++, data += step )
{
m_strm.GetBytes( src, src_pitch );
if( !color )
icvCvt_BGR5652Gray_8u_C2C1R( src, 0, data, 0, cvSize(m_width,1) );
else
icvCvt_BGR5652BGR_8u_C2C3R( src, 0, data, 0, cvSize(m_width,1) );
}
result = true;
break;
/************************* 24 BPP ************************/
case 24:
for( y = 0; y < m_height; y++, data += step )
{
m_strm.GetBytes( color ? data : src, src_pitch );
if( !color )
icvCvt_BGR2Gray_8u_C3C1R( src, 0, data, 0, cvSize(m_width,1) );
}
result = true;
break;
/************************* 32 BPP ************************/
case 32:
for( y = 0; y < m_height; y++, data += step )
{
m_strm.GetBytes( src, src_pitch );
if( !color )
icvCvt_BGRA2Gray_8u_C4C1R( src, 0, data, 0, cvSize(m_width,1) );
else
icvCvt_BGRA2BGR_8u_C4C3R( src, 0, data, 0, cvSize(m_width,1) );
}
result = true;
break;
default:
assert(0);
}
}
if( src != buffer ) delete[] src;
if( bgr != bgr_buffer ) delete[] bgr;
return result;
}
//////////////////////////////////////////////////////////////////////////////////////////
GrFmtBmpWriter::GrFmtBmpWriter( const char* filename ) : GrFmtWriter( filename )
{
}
GrFmtBmpWriter::~GrFmtBmpWriter()
{
}
bool GrFmtBmpWriter::WriteImage( const uchar* data, int step,
int width, int height, int /*depth*/, int channels )
{
bool result = false;
int fileStep = (width*channels + 3) & -4;
uchar zeropad[] = "\0\0\0\0";
assert( data && width > 0 && height > 0 && step >= fileStep );
if( m_strm.Open( m_filename ) )
{
int bitmapHeaderSize = 40;
int paletteSize = channels > 1 ? 0 : 1024;
int headerSize = 14 /* fileheader */ + bitmapHeaderSize + paletteSize;
PaletteEntry palette[256];
// write signature 'BM'
m_strm.PutBytes( fmtSignBmp, (int)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( channels << 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( channels == 1 )
{
FillGrayPalette( palette, 8 );
m_strm.PutBytes( palette, sizeof(palette));
}
width *= channels;
data += step*(height - 1);
for( ; height--; data -= step )
{
m_strm.PutBytes( data, width );
if( fileStep > width )
m_strm.PutBytes( zeropad, fileStep - width );
}
m_strm.Close();
result = true;
}
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -