in modules/imgproc/src/color.cpp [7924:8469]
void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
{
int stype = _src.type();
int scn = CV_MAT_CN(stype), depth = CV_MAT_DEPTH(stype), bidx;
CV_OCL_RUN( _src.dims() <= 2 && _dst.isUMat() && !(depth == CV_8U && (code == CV_Luv2BGR || code == CV_Luv2RGB)),
ocl_cvtColor(_src, _dst, code, dcn) )
Mat src = _src.getMat(), dst;
Size sz = src.size();
CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_32F );
CV_IPP_RUN(true, ipp_cvtColor(src, _dst, code, dcn));
switch( code )
{
case CV_BGR2BGRA: case CV_RGB2BGRA: case CV_BGRA2BGR:
case CV_RGBA2BGR: case CV_RGB2BGR: case CV_BGRA2RGBA:
CV_Assert( scn == 3 || scn == 4 );
dcn = code == CV_BGR2BGRA || code == CV_RGB2BGRA || code == CV_BGRA2RGBA ? 4 : 3;
bidx = code == CV_BGR2BGRA || code == CV_BGRA2BGR ? 0 : 2;
_dst.create( sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
if( depth == CV_8U )
{
#ifdef HAVE_TEGRA_OPTIMIZATION
if(tegra::useTegra() && tegra::cvtBGR2RGB(src, dst, bidx))
break;
#endif
CvtColorLoop(src, dst, RGB2RGB<uchar>(scn, dcn, bidx));
}
else if( depth == CV_16U )
CvtColorLoop(src, dst, RGB2RGB<ushort>(scn, dcn, bidx));
else
CvtColorLoop(src, dst, RGB2RGB<float>(scn, dcn, bidx));
break;
case CV_BGR2BGR565: case CV_BGR2BGR555: case CV_RGB2BGR565: case CV_RGB2BGR555:
case CV_BGRA2BGR565: case CV_BGRA2BGR555: case CV_RGBA2BGR565: case CV_RGBA2BGR555:
CV_Assert( (scn == 3 || scn == 4) && depth == CV_8U );
_dst.create(sz, CV_8UC2);
dst = _dst.getMat();
#ifdef HAVE_TEGRA_OPTIMIZATION
if(code == CV_BGR2BGR565 || code == CV_BGRA2BGR565 || code == CV_RGB2BGR565 || code == CV_RGBA2BGR565)
if(tegra::useTegra() && tegra::cvtRGB2RGB565(src, dst, code == CV_RGB2BGR565 || code == CV_RGBA2BGR565 ? 0 : 2))
break;
#endif
CvtColorLoop(src, dst, RGB2RGB5x5(scn,
code == CV_BGR2BGR565 || code == CV_BGR2BGR555 ||
code == CV_BGRA2BGR565 || code == CV_BGRA2BGR555 ? 0 : 2,
code == CV_BGR2BGR565 || code == CV_RGB2BGR565 ||
code == CV_BGRA2BGR565 || code == CV_RGBA2BGR565 ? 6 : 5 // green bits
));
break;
case CV_BGR5652BGR: case CV_BGR5552BGR: case CV_BGR5652RGB: case CV_BGR5552RGB:
case CV_BGR5652BGRA: case CV_BGR5552BGRA: case CV_BGR5652RGBA: case CV_BGR5552RGBA:
if(dcn <= 0) dcn = (code==CV_BGR5652BGRA || code==CV_BGR5552BGRA || code==CV_BGR5652RGBA || code==CV_BGR5552RGBA) ? 4 : 3;
CV_Assert( (dcn == 3 || dcn == 4) && scn == 2 && depth == CV_8U );
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
CvtColorLoop(src, dst, RGB5x52RGB(dcn,
code == CV_BGR5652BGR || code == CV_BGR5552BGR ||
code == CV_BGR5652BGRA || code == CV_BGR5552BGRA ? 0 : 2, // blue idx
code == CV_BGR5652BGR || code == CV_BGR5652RGB ||
code == CV_BGR5652BGRA || code == CV_BGR5652RGBA ? 6 : 5 // green bits
));
break;
case CV_BGR2GRAY: case CV_BGRA2GRAY: case CV_RGB2GRAY: case CV_RGBA2GRAY:
CV_Assert( scn == 3 || scn == 4 );
_dst.create(sz, CV_MAKETYPE(depth, 1));
dst = _dst.getMat();
bidx = code == CV_BGR2GRAY || code == CV_BGRA2GRAY ? 0 : 2;
if( depth == CV_8U )
{
#ifdef HAVE_TEGRA_OPTIMIZATION
if(tegra::useTegra() && tegra::cvtRGB2Gray(src, dst, bidx))
break;
#endif
CvtColorLoop(src, dst, RGB2Gray<uchar>(scn, bidx, 0));
}
else if( depth == CV_16U )
CvtColorLoop(src, dst, RGB2Gray<ushort>(scn, bidx, 0));
else
CvtColorLoop(src, dst, RGB2Gray<float>(scn, bidx, 0));
break;
case CV_BGR5652GRAY: case CV_BGR5552GRAY:
CV_Assert( scn == 2 && depth == CV_8U );
_dst.create(sz, CV_8UC1);
dst = _dst.getMat();
CvtColorLoop(src, dst, RGB5x52Gray(code == CV_BGR5652GRAY ? 6 : 5));
break;
case CV_GRAY2BGR: case CV_GRAY2BGRA:
if( dcn <= 0 ) dcn = (code==CV_GRAY2BGRA) ? 4 : 3;
CV_Assert( scn == 1 && (dcn == 3 || dcn == 4));
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
if( depth == CV_8U )
{
#ifdef HAVE_TEGRA_OPTIMIZATION
if(tegra::useTegra() && tegra::cvtGray2RGB(src, dst))
break;
#endif
CvtColorLoop(src, dst, Gray2RGB<uchar>(dcn));
}
else if( depth == CV_16U )
CvtColorLoop(src, dst, Gray2RGB<ushort>(dcn));
else
CvtColorLoop(src, dst, Gray2RGB<float>(dcn));
break;
case CV_GRAY2BGR565: case CV_GRAY2BGR555:
CV_Assert( scn == 1 && depth == CV_8U );
_dst.create(sz, CV_8UC2);
dst = _dst.getMat();
CvtColorLoop(src, dst, Gray2RGB5x5(code == CV_GRAY2BGR565 ? 6 : 5));
break;
case CV_BGR2YCrCb: case CV_RGB2YCrCb:
case CV_BGR2YUV: case CV_RGB2YUV:
{
CV_Assert( scn == 3 || scn == 4 );
bidx = code == CV_BGR2YCrCb || code == CV_BGR2YUV ? 0 : 2;
static const float yuv_f[] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f };
static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 };
const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f;
const int* coeffs_i = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_i;
_dst.create(sz, CV_MAKETYPE(depth, 3));
dst = _dst.getMat();
if( depth == CV_8U )
{
#ifdef HAVE_TEGRA_OPTIMIZATION
if((code == CV_RGB2YCrCb || code == CV_BGR2YCrCb) && tegra::useTegra() && tegra::cvtRGB2YCrCb(src, dst, bidx))
break;
#endif
CvtColorLoop(src, dst, RGB2YCrCb_i<uchar>(scn, bidx, coeffs_i));
}
else if( depth == CV_16U )
CvtColorLoop(src, dst, RGB2YCrCb_i<ushort>(scn, bidx, coeffs_i));
else
CvtColorLoop(src, dst, RGB2YCrCb_f<float>(scn, bidx, coeffs_f));
}
break;
case CV_YCrCb2BGR: case CV_YCrCb2RGB:
case CV_YUV2BGR: case CV_YUV2RGB:
{
if( dcn <= 0 ) dcn = 3;
CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) );
bidx = code == CV_YCrCb2BGR || code == CV_YUV2BGR ? 0 : 2;
static const float yuv_f[] = { 2.032f, -0.395f, -0.581f, 1.140f };
static const int yuv_i[] = { 33292, -6472, -9519, 18678 };
const float* coeffs_f = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_f;
const int* coeffs_i = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_i;
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
if( depth == CV_8U )
CvtColorLoop(src, dst, YCrCb2RGB_i<uchar>(dcn, bidx, coeffs_i));
else if( depth == CV_16U )
CvtColorLoop(src, dst, YCrCb2RGB_i<ushort>(dcn, bidx, coeffs_i));
else
CvtColorLoop(src, dst, YCrCb2RGB_f<float>(dcn, bidx, coeffs_f));
}
break;
case CV_BGR2XYZ: case CV_RGB2XYZ:
CV_Assert( scn == 3 || scn == 4 );
bidx = code == CV_BGR2XYZ ? 0 : 2;
_dst.create(sz, CV_MAKETYPE(depth, 3));
dst = _dst.getMat();
if( depth == CV_8U )
CvtColorLoop(src, dst, RGB2XYZ_i<uchar>(scn, bidx, 0));
else if( depth == CV_16U )
CvtColorLoop(src, dst, RGB2XYZ_i<ushort>(scn, bidx, 0));
else
CvtColorLoop(src, dst, RGB2XYZ_f<float>(scn, bidx, 0));
break;
case CV_XYZ2BGR: case CV_XYZ2RGB:
if( dcn <= 0 ) dcn = 3;
CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) );
bidx = code == CV_XYZ2BGR ? 0 : 2;
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
if( depth == CV_8U )
CvtColorLoop(src, dst, XYZ2RGB_i<uchar>(dcn, bidx, 0));
else if( depth == CV_16U )
CvtColorLoop(src, dst, XYZ2RGB_i<ushort>(dcn, bidx, 0));
else
CvtColorLoop(src, dst, XYZ2RGB_f<float>(dcn, bidx, 0));
break;
case CV_BGR2HSV: case CV_RGB2HSV: case CV_BGR2HSV_FULL: case CV_RGB2HSV_FULL:
case CV_BGR2HLS: case CV_RGB2HLS: case CV_BGR2HLS_FULL: case CV_RGB2HLS_FULL:
{
CV_Assert( (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) );
bidx = code == CV_BGR2HSV || code == CV_BGR2HLS ||
code == CV_BGR2HSV_FULL || code == CV_BGR2HLS_FULL ? 0 : 2;
int hrange = depth == CV_32F ? 360 : code == CV_BGR2HSV || code == CV_RGB2HSV ||
code == CV_BGR2HLS || code == CV_RGB2HLS ? 180 : 256;
_dst.create(sz, CV_MAKETYPE(depth, 3));
dst = _dst.getMat();
if( code == CV_BGR2HSV || code == CV_RGB2HSV ||
code == CV_BGR2HSV_FULL || code == CV_RGB2HSV_FULL )
{
#ifdef HAVE_TEGRA_OPTIMIZATION
if(tegra::useTegra() && tegra::cvtRGB2HSV(src, dst, bidx, hrange))
break;
#endif
if( depth == CV_8U )
CvtColorLoop(src, dst, RGB2HSV_b(scn, bidx, hrange));
else
CvtColorLoop(src, dst, RGB2HSV_f(scn, bidx, (float)hrange));
}
else
{
if( depth == CV_8U )
CvtColorLoop(src, dst, RGB2HLS_b(scn, bidx, hrange));
else
CvtColorLoop(src, dst, RGB2HLS_f(scn, bidx, (float)hrange));
}
}
break;
case CV_HSV2BGR: case CV_HSV2RGB: case CV_HSV2BGR_FULL: case CV_HSV2RGB_FULL:
case CV_HLS2BGR: case CV_HLS2RGB: case CV_HLS2BGR_FULL: case CV_HLS2RGB_FULL:
{
if( dcn <= 0 ) dcn = 3;
CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F) );
bidx = code == CV_HSV2BGR || code == CV_HLS2BGR ||
code == CV_HSV2BGR_FULL || code == CV_HLS2BGR_FULL ? 0 : 2;
int hrange = depth == CV_32F ? 360 : code == CV_HSV2BGR || code == CV_HSV2RGB ||
code == CV_HLS2BGR || code == CV_HLS2RGB ? 180 : 255;
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
if( code == CV_HSV2BGR || code == CV_HSV2RGB ||
code == CV_HSV2BGR_FULL || code == CV_HSV2RGB_FULL )
{
if( depth == CV_8U )
CvtColorLoop(src, dst, HSV2RGB_b(dcn, bidx, hrange));
else
CvtColorLoop(src, dst, HSV2RGB_f(dcn, bidx, (float)hrange));
}
else
{
if( depth == CV_8U )
CvtColorLoop(src, dst, HLS2RGB_b(dcn, bidx, hrange));
else
CvtColorLoop(src, dst, HLS2RGB_f(dcn, bidx, (float)hrange));
}
}
break;
case CV_BGR2Lab: case CV_RGB2Lab: case CV_LBGR2Lab: case CV_LRGB2Lab:
case CV_BGR2Luv: case CV_RGB2Luv: case CV_LBGR2Luv: case CV_LRGB2Luv:
{
CV_Assert( (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) );
bidx = code == CV_BGR2Lab || code == CV_BGR2Luv ||
code == CV_LBGR2Lab || code == CV_LBGR2Luv ? 0 : 2;
bool srgb = code == CV_BGR2Lab || code == CV_RGB2Lab ||
code == CV_BGR2Luv || code == CV_RGB2Luv;
_dst.create(sz, CV_MAKETYPE(depth, 3));
dst = _dst.getMat();
if( code == CV_BGR2Lab || code == CV_RGB2Lab ||
code == CV_LBGR2Lab || code == CV_LRGB2Lab )
{
if( depth == CV_8U )
CvtColorLoop(src, dst, RGB2Lab_b(scn, bidx, 0, 0, srgb));
else
CvtColorLoop(src, dst, RGB2Lab_f(scn, bidx, 0, 0, srgb));
}
else
{
if( depth == CV_8U )
CvtColorLoop(src, dst, RGB2Luv_b(scn, bidx, 0, 0, srgb));
else
CvtColorLoop(src, dst, RGB2Luv_f(scn, bidx, 0, 0, srgb));
}
}
break;
case CV_Lab2BGR: case CV_Lab2RGB: case CV_Lab2LBGR: case CV_Lab2LRGB:
case CV_Luv2BGR: case CV_Luv2RGB: case CV_Luv2LBGR: case CV_Luv2LRGB:
{
if( dcn <= 0 ) dcn = 3;
CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F) );
bidx = code == CV_Lab2BGR || code == CV_Luv2BGR ||
code == CV_Lab2LBGR || code == CV_Luv2LBGR ? 0 : 2;
bool srgb = code == CV_Lab2BGR || code == CV_Lab2RGB ||
code == CV_Luv2BGR || code == CV_Luv2RGB;
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
if( code == CV_Lab2BGR || code == CV_Lab2RGB ||
code == CV_Lab2LBGR || code == CV_Lab2LRGB )
{
if( depth == CV_8U )
CvtColorLoop(src, dst, Lab2RGB_b(dcn, bidx, 0, 0, srgb));
else
CvtColorLoop(src, dst, Lab2RGB_f(dcn, bidx, 0, 0, srgb));
}
else
{
if( depth == CV_8U )
CvtColorLoop(src, dst, Luv2RGB_b(dcn, bidx, 0, 0, srgb));
else
CvtColorLoop(src, dst, Luv2RGB_f(dcn, bidx, 0, 0, srgb));
}
}
break;
case CV_BayerBG2GRAY: case CV_BayerGB2GRAY: case CV_BayerRG2GRAY: case CV_BayerGR2GRAY:
case CV_BayerBG2BGR: case CV_BayerGB2BGR: case CV_BayerRG2BGR: case CV_BayerGR2BGR:
case CV_BayerBG2BGR_VNG: case CV_BayerGB2BGR_VNG: case CV_BayerRG2BGR_VNG: case CV_BayerGR2BGR_VNG:
case CV_BayerBG2BGR_EA: case CV_BayerGB2BGR_EA: case CV_BayerRG2BGR_EA: case CV_BayerGR2BGR_EA:
demosaicing(src, _dst, code, dcn);
break;
case CV_YUV2BGR_NV21: case CV_YUV2RGB_NV21: case CV_YUV2BGR_NV12: case CV_YUV2RGB_NV12:
case CV_YUV2BGRA_NV21: case CV_YUV2RGBA_NV21: case CV_YUV2BGRA_NV12: case CV_YUV2RGBA_NV12:
{
// http://www.fourcc.org/yuv.php#NV21 == yuv420sp -> a plane of 8 bit Y samples followed by an interleaved V/U plane containing 8 bit 2x2 subsampled chroma samples
// http://www.fourcc.org/yuv.php#NV12 -> a plane of 8 bit Y samples followed by an interleaved U/V plane containing 8 bit 2x2 subsampled colour difference samples
if (dcn <= 0) dcn = (code==CV_YUV420sp2BGRA || code==CV_YUV420sp2RGBA || code==CV_YUV2BGRA_NV12 || code==CV_YUV2RGBA_NV12) ? 4 : 3;
const int bIdx = (code==CV_YUV2BGR_NV21 || code==CV_YUV2BGRA_NV21 || code==CV_YUV2BGR_NV12 || code==CV_YUV2BGRA_NV12) ? 0 : 2;
const int uIdx = (code==CV_YUV2BGR_NV21 || code==CV_YUV2BGRA_NV21 || code==CV_YUV2RGB_NV21 || code==CV_YUV2RGBA_NV21) ? 1 : 0;
CV_Assert( dcn == 3 || dcn == 4 );
CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U );
Size dstSz(sz.width, sz.height * 2 / 3);
_dst.create(dstSz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
int srcstep = (int)src.step;
const uchar* y = src.ptr();
const uchar* uv = y + srcstep * dstSz.height;
switch(dcn*100 + bIdx * 10 + uIdx)
{
case 300: cvtYUV420sp2RGB<0, 0> (dst, srcstep, y, uv); break;
case 301: cvtYUV420sp2RGB<0, 1> (dst, srcstep, y, uv); break;
case 320: cvtYUV420sp2RGB<2, 0> (dst, srcstep, y, uv); break;
case 321: cvtYUV420sp2RGB<2, 1> (dst, srcstep, y, uv); break;
case 400: cvtYUV420sp2RGBA<0, 0>(dst, srcstep, y, uv); break;
case 401: cvtYUV420sp2RGBA<0, 1>(dst, srcstep, y, uv); break;
case 420: cvtYUV420sp2RGBA<2, 0>(dst, srcstep, y, uv); break;
case 421: cvtYUV420sp2RGBA<2, 1>(dst, srcstep, y, uv); break;
default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break;
};
}
break;
case CV_YUV2BGR_YV12: case CV_YUV2RGB_YV12: case CV_YUV2BGRA_YV12: case CV_YUV2RGBA_YV12:
case CV_YUV2BGR_IYUV: case CV_YUV2RGB_IYUV: case CV_YUV2BGRA_IYUV: case CV_YUV2RGBA_IYUV:
{
//http://www.fourcc.org/yuv.php#YV12 == yuv420p -> It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes.
//http://www.fourcc.org/yuv.php#IYUV == I420 -> It comprises an NxN Y plane followed by (N/2)x(N/2) U and V planes
if (dcn <= 0) dcn = (code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12 || code==CV_YUV2RGBA_IYUV || code==CV_YUV2BGRA_IYUV) ? 4 : 3;
const int bIdx = (code==CV_YUV2BGR_YV12 || code==CV_YUV2BGRA_YV12 || code==CV_YUV2BGR_IYUV || code==CV_YUV2BGRA_IYUV) ? 0 : 2;
const int uIdx = (code==CV_YUV2BGR_YV12 || code==CV_YUV2RGB_YV12 || code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12) ? 1 : 0;
CV_Assert( dcn == 3 || dcn == 4 );
CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U );
Size dstSz(sz.width, sz.height * 2 / 3);
_dst.create(dstSz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
int srcstep = (int)src.step;
const uchar* y = src.ptr();
const uchar* u = y + srcstep * dstSz.height;
const uchar* v = y + srcstep * (dstSz.height + dstSz.height/4) + (dstSz.width/2) * ((dstSz.height % 4)/2);
int ustepIdx = 0;
int vstepIdx = dstSz.height % 4 == 2 ? 1 : 0;
if(uIdx == 1) { std::swap(u ,v), std::swap(ustepIdx, vstepIdx); }
switch(dcn*10 + bIdx)
{
case 30: cvtYUV420p2RGB<0>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break;
case 32: cvtYUV420p2RGB<2>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break;
case 40: cvtYUV420p2RGBA<0>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break;
case 42: cvtYUV420p2RGBA<2>(dst, srcstep, y, u, v, ustepIdx, vstepIdx); break;
default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break;
};
}
break;
case CV_YUV2GRAY_420:
{
if (dcn <= 0) dcn = 1;
CV_Assert( dcn == 1 );
CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U );
Size dstSz(sz.width, sz.height * 2 / 3);
_dst.create(dstSz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
src(Range(0, dstSz.height), Range::all()).copyTo(dst);
}
break;
case CV_RGB2YUV_YV12: case CV_BGR2YUV_YV12: case CV_RGBA2YUV_YV12: case CV_BGRA2YUV_YV12:
case CV_RGB2YUV_IYUV: case CV_BGR2YUV_IYUV: case CV_RGBA2YUV_IYUV: case CV_BGRA2YUV_IYUV:
{
if (dcn <= 0) dcn = 1;
const int bIdx = (code == CV_BGR2YUV_IYUV || code == CV_BGRA2YUV_IYUV || code == CV_BGR2YUV_YV12 || code == CV_BGRA2YUV_YV12) ? 0 : 2;
const int uIdx = (code == CV_BGR2YUV_IYUV || code == CV_BGRA2YUV_IYUV || code == CV_RGB2YUV_IYUV || code == CV_RGBA2YUV_IYUV) ? 1 : 2;
CV_Assert( (scn == 3 || scn == 4) && depth == CV_8U );
CV_Assert( dcn == 1 );
CV_Assert( sz.width % 2 == 0 && sz.height % 2 == 0 );
Size dstSz(sz.width, sz.height / 2 * 3);
_dst.create(dstSz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
switch(bIdx + uIdx*10)
{
case 10: cvtRGBtoYUV420p<0, 1>(src, dst); break;
case 12: cvtRGBtoYUV420p<2, 1>(src, dst); break;
case 20: cvtRGBtoYUV420p<0, 2>(src, dst); break;
case 22: cvtRGBtoYUV420p<2, 2>(src, dst); break;
default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break;
};
}
break;
case CV_YUV2RGB_UYVY: case CV_YUV2BGR_UYVY: case CV_YUV2RGBA_UYVY: case CV_YUV2BGRA_UYVY:
case CV_YUV2RGB_YUY2: case CV_YUV2BGR_YUY2: case CV_YUV2RGB_YVYU: case CV_YUV2BGR_YVYU:
case CV_YUV2RGBA_YUY2: case CV_YUV2BGRA_YUY2: case CV_YUV2RGBA_YVYU: case CV_YUV2BGRA_YVYU:
{
//http://www.fourcc.org/yuv.php#UYVY
//http://www.fourcc.org/yuv.php#YUY2
//http://www.fourcc.org/yuv.php#YVYU
if (dcn <= 0) dcn = (code==CV_YUV2RGBA_UYVY || code==CV_YUV2BGRA_UYVY || code==CV_YUV2RGBA_YUY2 || code==CV_YUV2BGRA_YUY2 || code==CV_YUV2RGBA_YVYU || code==CV_YUV2BGRA_YVYU) ? 4 : 3;
const int bIdx = (code==CV_YUV2BGR_UYVY || code==CV_YUV2BGRA_UYVY || code==CV_YUV2BGR_YUY2 || code==CV_YUV2BGRA_YUY2 || code==CV_YUV2BGR_YVYU || code==CV_YUV2BGRA_YVYU) ? 0 : 2;
const int ycn = (code==CV_YUV2RGB_UYVY || code==CV_YUV2BGR_UYVY || code==CV_YUV2RGBA_UYVY || code==CV_YUV2BGRA_UYVY) ? 1 : 0;
const int uIdx = (code==CV_YUV2RGB_YVYU || code==CV_YUV2BGR_YVYU || code==CV_YUV2RGBA_YVYU || code==CV_YUV2BGRA_YVYU) ? 1 : 0;
CV_Assert( dcn == 3 || dcn == 4 );
CV_Assert( scn == 2 && depth == CV_8U );
_dst.create(sz, CV_8UC(dcn));
dst = _dst.getMat();
switch(dcn*1000 + bIdx*100 + uIdx*10 + ycn)
{
case 3000: cvtYUV422toRGB<0,0,0>(dst, (int)src.step, src.ptr<uchar>()); break;
case 3001: cvtYUV422toRGB<0,0,1>(dst, (int)src.step, src.ptr<uchar>()); break;
case 3010: cvtYUV422toRGB<0,1,0>(dst, (int)src.step, src.ptr<uchar>()); break;
case 3011: cvtYUV422toRGB<0,1,1>(dst, (int)src.step, src.ptr<uchar>()); break;
case 3200: cvtYUV422toRGB<2,0,0>(dst, (int)src.step, src.ptr<uchar>()); break;
case 3201: cvtYUV422toRGB<2,0,1>(dst, (int)src.step, src.ptr<uchar>()); break;
case 3210: cvtYUV422toRGB<2,1,0>(dst, (int)src.step, src.ptr<uchar>()); break;
case 3211: cvtYUV422toRGB<2,1,1>(dst, (int)src.step, src.ptr<uchar>()); break;
case 4000: cvtYUV422toRGBA<0,0,0>(dst, (int)src.step, src.ptr<uchar>()); break;
case 4001: cvtYUV422toRGBA<0,0,1>(dst, (int)src.step, src.ptr<uchar>()); break;
case 4010: cvtYUV422toRGBA<0,1,0>(dst, (int)src.step, src.ptr<uchar>()); break;
case 4011: cvtYUV422toRGBA<0,1,1>(dst, (int)src.step, src.ptr<uchar>()); break;
case 4200: cvtYUV422toRGBA<2,0,0>(dst, (int)src.step, src.ptr<uchar>()); break;
case 4201: cvtYUV422toRGBA<2,0,1>(dst, (int)src.step, src.ptr<uchar>()); break;
case 4210: cvtYUV422toRGBA<2,1,0>(dst, (int)src.step, src.ptr<uchar>()); break;
case 4211: cvtYUV422toRGBA<2,1,1>(dst, (int)src.step, src.ptr<uchar>()); break;
default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); break;
};
}
break;
case CV_YUV2GRAY_UYVY: case CV_YUV2GRAY_YUY2:
{
if (dcn <= 0) dcn = 1;
CV_Assert( dcn == 1 );
CV_Assert( scn == 2 && depth == CV_8U );
src.release(); // T-API datarace fixup
extractChannel(_src, _dst, code == CV_YUV2GRAY_UYVY ? 1 : 0);
}
break;
case CV_RGBA2mRGBA:
{
if (dcn <= 0) dcn = 4;
CV_Assert( scn == 4 && dcn == 4 );
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
if( depth == CV_8U )
{
CvtColorLoop(src, dst, RGBA2mRGBA<uchar>());
}
else
{
CV_Error( CV_StsBadArg, "Unsupported image depth" );
}
}
break;
case CV_mRGBA2RGBA:
{
if (dcn <= 0) dcn = 4;
CV_Assert( scn == 4 && dcn == 4 );
_dst.create(sz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
if( depth == CV_8U )
CvtColorLoop(src, dst, mRGBA2RGBA<uchar>());
else
{
CV_Error( CV_StsBadArg, "Unsupported image depth" );
}
}
break;
default:
CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
}
}