mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
Merge pull request #20875 from Harvey-Huang:master
* bmp specified BI_BITFIELDS should take care RGBA bit mask * change the name * support xrgb bmp file * support xrgb bmp file(add test case) * update testing code
This commit is contained in:
parent
d376fe9e17
commit
9267536fee
@ -58,6 +58,7 @@ BmpDecoder::BmpDecoder()
|
|||||||
m_origin = ORIGIN_TL;
|
m_origin = ORIGIN_TL;
|
||||||
m_bpp = 0;
|
m_bpp = 0;
|
||||||
m_rle_code = BMP_RGB;
|
m_rle_code = BMP_RGB;
|
||||||
|
initMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -97,6 +98,7 @@ bool BmpDecoder::readHeader()
|
|||||||
int size = m_strm.getDWord();
|
int size = m_strm.getDWord();
|
||||||
CV_Assert(size > 0); // overflow, 2Gb limit
|
CV_Assert(size > 0); // overflow, 2Gb limit
|
||||||
|
|
||||||
|
initMask();
|
||||||
if( size >= 36 )
|
if( size >= 36 )
|
||||||
{
|
{
|
||||||
m_width = m_strm.getDWord();
|
m_width = m_strm.getDWord();
|
||||||
@ -107,7 +109,30 @@ bool BmpDecoder::readHeader()
|
|||||||
m_rle_code = (BmpCompression)m_rle_code_;
|
m_rle_code = (BmpCompression)m_rle_code_;
|
||||||
m_strm.skip(12);
|
m_strm.skip(12);
|
||||||
int clrused = m_strm.getDWord();
|
int clrused = m_strm.getDWord();
|
||||||
m_strm.skip( size - 36 );
|
|
||||||
|
if( m_bpp == 32 && m_rle_code == BMP_BITFIELDS && size >= 56 )
|
||||||
|
{
|
||||||
|
m_strm.skip(4); //important colors
|
||||||
|
//0 is Red channel bit mask, 1 is Green channel bit mask, 2 is Blue channel bit mask, 3 is Alpha channel bit mask
|
||||||
|
for( int index_rgba = 0; index_rgba < 4; ++index_rgba )
|
||||||
|
{
|
||||||
|
uint mask = m_strm.getDWord();
|
||||||
|
m_rgba_mask[index_rgba] = mask;
|
||||||
|
if(mask != 0)
|
||||||
|
{
|
||||||
|
int bit_count = 0;
|
||||||
|
while(!(mask & 1))
|
||||||
|
{
|
||||||
|
mask >>= 1;
|
||||||
|
++bit_count;
|
||||||
|
}
|
||||||
|
m_rgba_bit_offset[index_rgba] = bit_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_strm.skip( size - 56 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_strm.skip( size - 36 );
|
||||||
|
|
||||||
if( m_width > 0 && m_height != 0 &&
|
if( m_width > 0 && m_height != 0 &&
|
||||||
(((m_bpp == 1 || m_bpp == 4 || m_bpp == 8 ||
|
(((m_bpp == 1 || m_bpp == 4 || m_bpp == 8 ||
|
||||||
@ -486,8 +511,14 @@ decode_rle8_bad: ;
|
|||||||
icvCvt_BGRA2Gray_8u_C4C1R( src, 0, data, 0, Size(m_width,1) );
|
icvCvt_BGRA2Gray_8u_C4C1R( src, 0, data, 0, Size(m_width,1) );
|
||||||
else if( img.channels() == 3 )
|
else if( img.channels() == 3 )
|
||||||
icvCvt_BGRA2BGR_8u_C4C3R(src, 0, data, 0, Size(m_width, 1));
|
icvCvt_BGRA2BGR_8u_C4C3R(src, 0, data, 0, Size(m_width, 1));
|
||||||
else if( img.channels() == 4 )
|
else if ( img.channels() == 4 )
|
||||||
memcpy(data, src, m_width * 4);
|
{
|
||||||
|
bool has_bit_mask = (m_rgba_bit_offset[0] >= 0) && (m_rgba_bit_offset[1] >= 0) && (m_rgba_bit_offset[2] >= 0);
|
||||||
|
if ( has_bit_mask )
|
||||||
|
maskBGRA(data, src, m_width);
|
||||||
|
else
|
||||||
|
memcpy(data, src, m_width * 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
@ -503,7 +534,26 @@ decode_rle8_bad: ;
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BmpDecoder::initMask()
|
||||||
|
{
|
||||||
|
memset(m_rgba_mask, 0, sizeof(m_rgba_mask));
|
||||||
|
memset(m_rgba_bit_offset, -1, sizeof(m_rgba_bit_offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BmpDecoder::maskBGRA(uchar* des, uchar* src, int num)
|
||||||
|
{
|
||||||
|
for( int i = 0; i < num; i++, des += 4, src += 4 )
|
||||||
|
{
|
||||||
|
uint data = *((uint*)src);
|
||||||
|
des[0] = (uchar)((m_rgba_mask[2] & data) >> m_rgba_bit_offset[2]);
|
||||||
|
des[1] = (uchar)((m_rgba_mask[1] & data) >> m_rgba_bit_offset[1]);
|
||||||
|
des[2] = (uchar)((m_rgba_mask[0] & data) >> m_rgba_bit_offset[0]);
|
||||||
|
if (m_rgba_bit_offset[3] >= 0)
|
||||||
|
des[3] = (uchar)((m_rgba_mask[3] & data) >> m_rgba_bit_offset[3]);
|
||||||
|
else
|
||||||
|
des[3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
BmpEncoder::BmpEncoder()
|
BmpEncoder::BmpEncoder()
|
||||||
|
@ -73,6 +73,9 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
void initMask();
|
||||||
|
void maskBGRA(uchar* des, uchar* src, int num);
|
||||||
|
|
||||||
enum Origin
|
enum Origin
|
||||||
{
|
{
|
||||||
ORIGIN_TL = 0,
|
ORIGIN_TL = 0,
|
||||||
@ -85,6 +88,8 @@ protected:
|
|||||||
int m_bpp;
|
int m_bpp;
|
||||||
int m_offset;
|
int m_offset;
|
||||||
BmpCompression m_rle_code;
|
BmpCompression m_rle_code;
|
||||||
|
uint m_rgba_mask[4];
|
||||||
|
int m_rgba_bit_offset[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -295,6 +295,32 @@ TEST(Imgcodecs_Bmp, read_rle8)
|
|||||||
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), rle, ord);
|
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), rle, ord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Imgcodecs_Bmp, rgba_bit_mask)
|
||||||
|
{
|
||||||
|
const string root = cvtest::TS::ptr()->get_data_path();
|
||||||
|
const string filenameInput = root + "readwrite/test_rgba_mask.bmp";
|
||||||
|
|
||||||
|
const Mat img = cv::imread(filenameInput, IMREAD_UNCHANGED);
|
||||||
|
ASSERT_FALSE(img.empty());
|
||||||
|
ASSERT_EQ(CV_8UC4, img.type());
|
||||||
|
|
||||||
|
const uchar* data = img.ptr();
|
||||||
|
ASSERT_EQ(data[3], 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Imgcodecs_Bmp, read_32bit_xrgb)
|
||||||
|
{
|
||||||
|
const string root = cvtest::TS::ptr()->get_data_path();
|
||||||
|
const string filenameInput = root + "readwrite/test_32bit_xrgb.bmp";
|
||||||
|
|
||||||
|
const Mat img = cv::imread(filenameInput, IMREAD_UNCHANGED);
|
||||||
|
ASSERT_FALSE(img.empty());
|
||||||
|
ASSERT_EQ(CV_8UC4, img.type());
|
||||||
|
|
||||||
|
const uchar* data = img.ptr();
|
||||||
|
ASSERT_EQ(data[3], 255);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_IMGCODEC_HDR
|
#ifdef HAVE_IMGCODEC_HDR
|
||||||
TEST(Imgcodecs_Hdr, regression)
|
TEST(Imgcodecs_Hdr, regression)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user