mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
Merge branch 4.x
This commit is contained in:
@@ -127,6 +127,7 @@ bool BmpDecoder::readHeader()
|
||||
++bit_count;
|
||||
}
|
||||
m_rgba_bit_offset[index_rgba] = bit_count;
|
||||
m_rgba_scale_factor[index_rgba] = 255.0f / mask;
|
||||
}
|
||||
}
|
||||
m_strm.skip( size - 56 );
|
||||
@@ -503,21 +504,33 @@ decode_rle8_bad: ;
|
||||
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, Size(m_width,1) );
|
||||
else if( img.channels() == 3 )
|
||||
icvCvt_BGRA2BGR_8u_C4C3R(src, 0, data, 0, Size(m_width, 1));
|
||||
else if ( img.channels() == 4 )
|
||||
bool has_bit_mask = (m_rgba_bit_offset[0] >= 0) && (m_rgba_bit_offset[1] >= 0) && (m_rgba_bit_offset[2] >= 0);
|
||||
for( y = 0; y < m_height; y++, data += step )
|
||||
{
|
||||
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);
|
||||
m_strm.getBytes( src, src_pitch );
|
||||
|
||||
if( !color )
|
||||
{
|
||||
if ( has_bit_mask )
|
||||
maskBGRAtoGray(data, src, m_width);
|
||||
else
|
||||
icvCvt_BGRA2Gray_8u_C4C1R( src, 0, data, 0, Size(m_width,1) );
|
||||
}
|
||||
else if( img.channels() == 3 )
|
||||
{
|
||||
if ( has_bit_mask )
|
||||
maskBGRA(data, src, m_width, false);
|
||||
else
|
||||
icvCvt_BGRA2BGR_8u_C4C3R(src, 0, data, 0, Size(m_width, 1));
|
||||
}
|
||||
else if ( img.channels() == 4 )
|
||||
{
|
||||
if ( has_bit_mask )
|
||||
maskBGRA(data, src, m_width, true);
|
||||
else
|
||||
memcpy(data, src, m_width * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
@@ -538,20 +551,40 @@ void BmpDecoder::initMask()
|
||||
{
|
||||
memset(m_rgba_mask, 0, sizeof(m_rgba_mask));
|
||||
memset(m_rgba_bit_offset, -1, sizeof(m_rgba_bit_offset));
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
m_rgba_scale_factor[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void BmpDecoder::maskBGRA(uchar* des, uchar* src, int num)
|
||||
void BmpDecoder::maskBGRA(uchar* des, const uchar* src, int num, bool alpha_required)
|
||||
{
|
||||
for( int i = 0; i < num; i++, des += 4, src += 4 )
|
||||
int dest_stride = alpha_required ? 4 : 3;
|
||||
for( int i = 0; i < num; i++, des += dest_stride, 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;
|
||||
des[0] = (uchar)(((m_rgba_mask[2] & data) >> m_rgba_bit_offset[2]) * m_rgba_scale_factor[2]);
|
||||
des[1] = (uchar)(((m_rgba_mask[1] & data) >> m_rgba_bit_offset[1]) * m_rgba_scale_factor[1]);
|
||||
des[2] = (uchar)(((m_rgba_mask[0] & data) >> m_rgba_bit_offset[0]) * m_rgba_scale_factor[0]);
|
||||
if (alpha_required)
|
||||
{
|
||||
if (m_rgba_bit_offset[3] >= 0)
|
||||
des[3] = (uchar)(((m_rgba_mask[3] & data) >> m_rgba_bit_offset[3]) * m_rgba_scale_factor[3]);
|
||||
else
|
||||
des[3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BmpDecoder::maskBGRAtoGray(uchar* des, const uchar* src, int num)
|
||||
{
|
||||
for( int i = 0; i < num; i++, des++, src += 4 )
|
||||
{
|
||||
uint data = *((uint*)src);
|
||||
int red = (uchar)(((m_rgba_mask[0] & data) >> m_rgba_bit_offset[0]) * m_rgba_scale_factor[0]);
|
||||
int green = (uchar)(((m_rgba_mask[1] & data) >> m_rgba_bit_offset[1]) * m_rgba_scale_factor[1]);
|
||||
int blue = (uchar)(((m_rgba_mask[2] & data) >> m_rgba_bit_offset[2]) * m_rgba_scale_factor[2]);
|
||||
|
||||
*des = (uchar)(0.299f * red + 0.587f * green + 0.114f * blue);
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -74,7 +74,8 @@ public:
|
||||
protected:
|
||||
|
||||
void initMask();
|
||||
void maskBGRA(uchar* des, uchar* src, int num);
|
||||
void maskBGRA(uchar* des, const uchar* src, int num, bool alpha_required);
|
||||
void maskBGRAtoGray(uchar* des, const uchar* src, int num);
|
||||
|
||||
enum Origin
|
||||
{
|
||||
@@ -90,6 +91,7 @@ protected:
|
||||
BmpCompression m_rle_code;
|
||||
uint m_rgba_mask[4];
|
||||
int m_rgba_bit_offset[4];
|
||||
float m_rgba_scale_factor[4];
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -695,14 +695,14 @@ bool PAMEncoder::write( const Mat& img, const std::vector<int>& params )
|
||||
|
||||
/* write header */
|
||||
tmp = 0;
|
||||
tmp += sprintf( buffer, "P7\n");
|
||||
tmp += sprintf( buffer + tmp, "WIDTH %d\n", width);
|
||||
tmp += sprintf( buffer + tmp, "HEIGHT %d\n", height);
|
||||
tmp += sprintf( buffer + tmp, "DEPTH %d\n", img.channels());
|
||||
tmp += sprintf( buffer + tmp, "MAXVAL %d\n", (1 << img.elemSize1()*8) - 1);
|
||||
tmp += snprintf( buffer, bufsize, "P7\n");
|
||||
tmp += snprintf( buffer + tmp, bufsize - tmp, "WIDTH %d\n", width);
|
||||
tmp += snprintf( buffer + tmp, bufsize - tmp, "HEIGHT %d\n", height);
|
||||
tmp += snprintf( buffer + tmp, bufsize - tmp, "DEPTH %d\n", img.channels());
|
||||
tmp += snprintf( buffer + tmp, bufsize - tmp, "MAXVAL %d\n", (1 << img.elemSize1()*8) - 1);
|
||||
if (fmt)
|
||||
tmp += sprintf( buffer + tmp, "TUPLTYPE %s\n", fmt->name );
|
||||
sprintf( buffer + tmp, "ENDHDR\n" );
|
||||
tmp += snprintf( buffer + tmp, bufsize - tmp, "TUPLTYPE %s\n", fmt->name );
|
||||
snprintf( buffer + tmp, bufsize - tmp, "ENDHDR\n" );
|
||||
|
||||
strm.putBytes( buffer, (int)strlen(buffer) );
|
||||
/* write data */
|
||||
|
||||
@@ -467,12 +467,12 @@ bool PxMEncoder::write(const Mat& img, const std::vector<int>& params)
|
||||
const int code = ((mode == PXM_TYPE_PBM) ? 1 : (mode == PXM_TYPE_PGM) ? 2 : 3)
|
||||
+ (isBinary ? 3 : 0);
|
||||
|
||||
int header_sz = sprintf(buffer, "P%c\n%d %d\n",
|
||||
int header_sz = snprintf(buffer, bufferSize, "P%c\n%d %d\n",
|
||||
(char)('0' + code), width, height);
|
||||
CV_Assert(header_sz > 0);
|
||||
if (mode != PXM_TYPE_PBM)
|
||||
{
|
||||
int sz = sprintf(&buffer[header_sz], "%d\n", (1 << depth) - 1);
|
||||
int sz = snprintf(&buffer[header_sz], bufferSize - header_sz, "%d\n", (1 << depth) - 1);
|
||||
CV_Assert(sz > 0);
|
||||
header_sz += sz;
|
||||
}
|
||||
@@ -560,11 +560,11 @@ bool PxMEncoder::write(const Mat& img, const std::vector<int>& params)
|
||||
{
|
||||
for( x = 0; x < width*channels; x += channels )
|
||||
{
|
||||
sprintf( ptr, "% 4d", data[x + 2] );
|
||||
snprintf( ptr, bufferSize - (ptr - buffer), "% 4d", data[x + 2] );
|
||||
ptr += 4;
|
||||
sprintf( ptr, "% 4d", data[x + 1] );
|
||||
snprintf( ptr, bufferSize - (ptr - buffer), "% 4d", data[x + 1] );
|
||||
ptr += 4;
|
||||
sprintf( ptr, "% 4d", data[x] );
|
||||
snprintf( ptr, bufferSize - (ptr - buffer), "% 4d", data[x] );
|
||||
ptr += 4;
|
||||
*ptr++ = ' ';
|
||||
*ptr++ = ' ';
|
||||
@@ -574,11 +574,11 @@ bool PxMEncoder::write(const Mat& img, const std::vector<int>& params)
|
||||
{
|
||||
for( x = 0; x < width*channels; x += channels )
|
||||
{
|
||||
sprintf( ptr, "% 6d", ((const ushort *)data)[x + 2] );
|
||||
snprintf( ptr, bufferSize - (ptr - buffer), "% 6d", ((const ushort *)data)[x + 2] );
|
||||
ptr += 6;
|
||||
sprintf( ptr, "% 6d", ((const ushort *)data)[x + 1] );
|
||||
snprintf( ptr, bufferSize - (ptr - buffer), "% 6d", ((const ushort *)data)[x + 1] );
|
||||
ptr += 6;
|
||||
sprintf( ptr, "% 6d", ((const ushort *)data)[x] );
|
||||
snprintf( ptr, bufferSize - (ptr - buffer), "% 6d", ((const ushort *)data)[x] );
|
||||
ptr += 6;
|
||||
*ptr++ = ' ';
|
||||
*ptr++ = ' ';
|
||||
@@ -591,7 +591,7 @@ bool PxMEncoder::write(const Mat& img, const std::vector<int>& params)
|
||||
{
|
||||
for( x = 0; x < width; x++ )
|
||||
{
|
||||
sprintf( ptr, "% 4d", data[x] );
|
||||
snprintf( ptr, bufferSize - (ptr - buffer), "% 4d", data[x] );
|
||||
ptr += 4;
|
||||
}
|
||||
}
|
||||
@@ -599,7 +599,7 @@ bool PxMEncoder::write(const Mat& img, const std::vector<int>& params)
|
||||
{
|
||||
for( x = 0; x < width; x++ )
|
||||
{
|
||||
sprintf( ptr, "% 6d", ((const ushort *)data)[x] );
|
||||
snprintf( ptr, bufferSize - (ptr - buffer), "% 6d", ((const ushort *)data)[x] );
|
||||
ptr += 6;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,9 @@ using namespace tiff_dummy_namespace;
|
||||
namespace cv
|
||||
{
|
||||
|
||||
// to extend cvtColor() to support CV_8S, CV_16S, CV_32S and CV_64F.
|
||||
static void extend_cvtColor( InputArray _src, OutputArray _dst, int code );
|
||||
|
||||
#define CV_TIFF_CHECK_CALL(call) \
|
||||
if (0 == (call)) { \
|
||||
CV_LOG_WARNING(NULL, "OpenCV TIFF(line " << __LINE__ << "): failed " #call); \
|
||||
@@ -1039,9 +1042,9 @@ bool TiffDecoder::readData( Mat& img )
|
||||
Rect roi_tile(0, 0, tile_width, tile_height);
|
||||
Rect roi_img(x, img_y, tile_width, tile_height);
|
||||
if (!m_hdr && ncn == 3)
|
||||
cvtColor(m_tile(roi_tile), img(roi_img), COLOR_RGB2BGR);
|
||||
extend_cvtColor(m_tile(roi_tile), img(roi_img), COLOR_RGB2BGR);
|
||||
else if (!m_hdr && ncn == 4)
|
||||
cvtColor(m_tile(roi_tile), img(roi_img), COLOR_RGBA2BGRA);
|
||||
extend_cvtColor(m_tile(roi_tile), img(roi_img), COLOR_RGBA2BGRA);
|
||||
else
|
||||
m_tile(roi_tile).copyTo(img(roi_img));
|
||||
break;
|
||||
@@ -1279,13 +1282,17 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
|
||||
break;
|
||||
}
|
||||
|
||||
case CV_32F:
|
||||
sample_format = SAMPLEFORMAT_IEEEFP;
|
||||
/* FALLTHRU */
|
||||
case CV_32S:
|
||||
{
|
||||
bitsPerChannel = 32;
|
||||
sample_format = SAMPLEFORMAT_INT;
|
||||
break;
|
||||
}
|
||||
case CV_32F:
|
||||
{
|
||||
bitsPerChannel = 32;
|
||||
page_compression = COMPRESSION_NONE;
|
||||
sample_format = SAMPLEFORMAT_IEEEFP;
|
||||
break;
|
||||
}
|
||||
case CV_64F:
|
||||
@@ -1356,13 +1363,13 @@ bool TiffEncoder::writeLibTiff( const std::vector<Mat>& img_vec, const std::vect
|
||||
|
||||
case 3:
|
||||
{
|
||||
cvtColor(img(Rect(0, y, width, 1)), (const Mat&)m_buffer, COLOR_BGR2RGB);
|
||||
extend_cvtColor(img(Rect(0, y, width, 1)), (const Mat&)m_buffer, COLOR_BGR2RGB);
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
cvtColor(img(Rect(0, y, width, 1)), (const Mat&)m_buffer, COLOR_BGRA2RGBA);
|
||||
extend_cvtColor(img(Rect(0, y, width, 1)), (const Mat&)m_buffer, COLOR_BGRA2RGBA);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1424,6 +1431,57 @@ bool TiffEncoder::write( const Mat& img, const std::vector<int>& params)
|
||||
return writeLibTiff(img_vec, params);
|
||||
}
|
||||
|
||||
static void extend_cvtColor( InputArray _src, OutputArray _dst, int code )
|
||||
{
|
||||
CV_Assert( !_src.empty() );
|
||||
CV_Assert( _src.dims() == 2 );
|
||||
|
||||
// This function extend_cvtColor reorders the src channels with only thg limited condition.
|
||||
// Otherwise, it calls cvtColor.
|
||||
|
||||
const int stype = _src.type();
|
||||
if(!
|
||||
(
|
||||
(
|
||||
( stype == CV_8SC3 ) || ( stype == CV_8SC4 ) ||
|
||||
( stype == CV_16SC3 ) || ( stype == CV_16SC4 ) ||
|
||||
( stype == CV_32SC3 ) || ( stype == CV_32SC4 ) ||
|
||||
( stype == CV_64FC3 ) || ( stype == CV_64FC4 )
|
||||
)
|
||||
&&
|
||||
(
|
||||
( code == COLOR_BGR2RGB ) || ( code == COLOR_BGRA2RGBA )
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
cvtColor( _src, _dst, code );
|
||||
return;
|
||||
}
|
||||
|
||||
Mat src = _src.getMat();
|
||||
|
||||
// cv::mixChannels requires the output arrays to be pre-allocated before calling the function.
|
||||
_dst.create( _src.size(), stype );
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
// BGR to RGB or BGRA to RGBA
|
||||
// src[0] -> dst[2]
|
||||
// src[1] -> dst[1]
|
||||
// src[2] -> dst[0]
|
||||
// src[3] -> dst[3] if src has alpha channel.
|
||||
std::vector<int> fromTo;
|
||||
fromTo.push_back(0); fromTo.push_back(2);
|
||||
fromTo.push_back(1); fromTo.push_back(1);
|
||||
fromTo.push_back(2); fromTo.push_back(0);
|
||||
if ( code == COLOR_BGRA2RGBA )
|
||||
{
|
||||
fromTo.push_back(3); fromTo.push_back(3);
|
||||
}
|
||||
|
||||
cv::mixChannels( src, dst, fromTo );
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user