2665 |
2665 |
}
|
2666 |
2666 |
}
|
2667 |
2667 |
|
|
2668 |
///////////////////////////////////// YUV422 -> RGB /////////////////////////////////////
|
|
2669 |
|
|
2670 |
template<int bIdx, int uIdx, int yIdx>
|
|
2671 |
struct YUV422i2RGB888Invoker
|
|
2672 |
{
|
|
2673 |
Mat* dst;
|
|
2674 |
const uchar* my1;
|
|
2675 |
int width, stride;
|
|
2676 |
|
|
2677 |
YUV422i2RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1)
|
|
2678 |
: dst(_dst), my1(_y1), width(_dst->cols), stride(_stride) {}
|
|
2679 |
|
|
2680 |
void operator()(const BlockedRange& range) const
|
|
2681 |
{
|
|
2682 |
int rangeBegin = range.begin();
|
|
2683 |
int rangeEnd = range.end();
|
|
2684 |
|
|
2685 |
//R = 1.164(Y - 16) + 1.596(V - 128)
|
|
2686 |
//G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
|
|
2687 |
//B = 1.164(Y - 16) + 2.018(U - 128)
|
|
2688 |
|
|
2689 |
//R = (1220542(Y - 16) + 1673527(V - 128) + (1 << 19)) >> 20
|
|
2690 |
//G = (1220542(Y - 16) - 852492(V - 128) - 409993(U - 128) + (1 << 19)) >> 20
|
|
2691 |
//B = (1220542(Y - 16) + 2116026(U - 128) + (1 << 19)) >> 20
|
|
2692 |
|
|
2693 |
const int cY = 1220542;
|
|
2694 |
const int cUB = 2116026;
|
|
2695 |
const int cUG = -409993;
|
|
2696 |
const int cVG = -852492;
|
|
2697 |
const int cVR = 1673527;
|
|
2698 |
const int YUV422_SHIFT = 20;
|
|
2699 |
const int vIdx = (2 + uIdx) % 4;
|
|
2700 |
|
|
2701 |
const uchar* yuv_src = my1 + rangeBegin * stride;
|
|
2702 |
|
|
2703 |
for (int j = rangeBegin; j < rangeEnd; j ++, yuv_src += stride)
|
|
2704 |
{
|
|
2705 |
uchar* row = dst->ptr<uchar>(j);
|
|
2706 |
|
|
2707 |
for (int i = 0; i < 2 * width; i += 4, row += 6)
|
|
2708 |
{
|
|
2709 |
int u = int(yuv_src[i + uIdx]) - 128;
|
|
2710 |
int v = int(yuv_src[i + vIdx]) - 128;
|
|
2711 |
|
|
2712 |
int ruv = (1 << (YUV422_SHIFT - 1)) + cVR * v;
|
|
2713 |
int guv = (1 << (YUV422_SHIFT - 1)) + cVG * v + cUG * u;
|
|
2714 |
int buv = (1 << (YUV422_SHIFT - 1)) + cUB * u;
|
|
2715 |
|
|
2716 |
int y00 = std::max(0, int(yuv_src[i + yIdx]) - 16) * cY;
|
|
2717 |
row[2-bIdx] = saturate_cast<uchar>((y00 + ruv) >> YUV422_SHIFT);
|
|
2718 |
row[1] = saturate_cast<uchar>((y00 + guv) >> YUV422_SHIFT);
|
|
2719 |
row[bIdx] = saturate_cast<uchar>((y00 + buv) >> YUV422_SHIFT);
|
|
2720 |
|
|
2721 |
int y01 = std::max(0, int(yuv_src[i + yIdx + 2]) - 16) * cY;
|
|
2722 |
row[5-bIdx] = saturate_cast<uchar>((y01 + ruv) >> YUV422_SHIFT);
|
|
2723 |
row[4] = saturate_cast<uchar>((y01 + guv) >> YUV422_SHIFT);
|
|
2724 |
row[3+bIdx] = saturate_cast<uchar>((y01 + buv) >> YUV422_SHIFT);
|
|
2725 |
|
|
2726 |
}
|
|
2727 |
}
|
|
2728 |
}
|
|
2729 |
};
|
|
2730 |
|
|
2731 |
template<int bIdx, int uIdx, int yIdx>
|
|
2732 |
struct YUV422i2RGBA888Invoker
|
|
2733 |
{
|
|
2734 |
Mat* dst;
|
|
2735 |
const uchar* my1;
|
|
2736 |
int width, stride;
|
|
2737 |
|
|
2738 |
YUV422i2RGBA888Invoker(Mat* _dst, int _stride, const uchar* _y1)
|
|
2739 |
: dst(_dst), my1(_y1), width(_dst->cols), stride(_stride) {}
|
|
2740 |
|
|
2741 |
void operator()(const BlockedRange& range) const
|
|
2742 |
{
|
|
2743 |
int rangeBegin = range.begin();
|
|
2744 |
int rangeEnd = range.end();
|
|
2745 |
|
|
2746 |
//R = 1.164(Y - 16) + 1.596(V - 128)
|
|
2747 |
//G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
|
|
2748 |
//B = 1.164(Y - 16) + 2.018(U - 128)
|
|
2749 |
|
|
2750 |
//R = (1220542(Y - 16) + 1673527(V - 128) + (1 << 19)) >> 20
|
|
2751 |
//G = (1220542(Y - 16) - 852492(V - 128) - 409993(U - 128) + (1 << 19)) >> 20
|
|
2752 |
//B = (1220542(Y - 16) + 2116026(U - 128) + (1 << 19)) >> 20
|
|
2753 |
|
|
2754 |
const int cY = 1220542;
|
|
2755 |
const int cUB = 2116026;
|
|
2756 |
const int cUG = -409993;
|
|
2757 |
const int cVG = -852492;
|
|
2758 |
const int cVR = 1673527;
|
|
2759 |
const int YUV422_SHIFT = 20;
|
|
2760 |
const int vIdx = (2 + uIdx) % 4;
|
|
2761 |
|
|
2762 |
const uchar* yuv_src = my1 + rangeBegin * stride;
|
|
2763 |
|
|
2764 |
for (int j = rangeBegin; j < rangeEnd; j ++, yuv_src += stride)
|
|
2765 |
{
|
|
2766 |
uchar* row = dst->ptr<uchar>(j);
|
|
2767 |
|
|
2768 |
for (int i = 0; i < 2 * width; i += 4, row += 8)
|
|
2769 |
{
|
|
2770 |
int u = int(yuv_src[i + uIdx]) - 128;
|
|
2771 |
int v = int(yuv_src[i + vIdx]) - 128;
|
|
2772 |
|
|
2773 |
int ruv = (1 << (YUV422_SHIFT - 1)) + cVR * v;
|
|
2774 |
int guv = (1 << (YUV422_SHIFT - 1)) + cVG * v + cUG * u;
|
|
2775 |
int buv = (1 << (YUV422_SHIFT - 1)) + cUB * u;
|
|
2776 |
|
|
2777 |
int y00 = std::max(0, int(yuv_src[i + yIdx]) - 16) * cY;
|
|
2778 |
row[2-bIdx] = saturate_cast<uchar>((y00 + ruv) >> YUV422_SHIFT);
|
|
2779 |
row[1] = saturate_cast<uchar>((y00 + guv) >> YUV422_SHIFT);
|
|
2780 |
row[bIdx] = saturate_cast<uchar>((y00 + buv) >> YUV422_SHIFT);
|
|
2781 |
row[3] = uchar(0xff);
|
|
2782 |
|
|
2783 |
int y01 = std::max(0, int(yuv_src[i + yIdx + 2]) - 16) * cY;
|
|
2784 |
row[6-bIdx] = saturate_cast<uchar>((y01 + ruv) >> YUV422_SHIFT);
|
|
2785 |
row[5] = saturate_cast<uchar>((y01 + guv) >> YUV422_SHIFT);
|
|
2786 |
row[4+bIdx] = saturate_cast<uchar>((y01 + buv) >> YUV422_SHIFT);
|
|
2787 |
row[7] = uchar(0xff);
|
|
2788 |
|
|
2789 |
}
|
|
2790 |
}
|
|
2791 |
}
|
|
2792 |
};
|
|
2793 |
|
|
2794 |
|
|
2795 |
#define MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION (320*240)
|
|
2796 |
template<int bIdx, int uIdx, int yIdx>
|
|
2797 |
inline void cvtYUV422i2RGB(Mat& _dst, int _stride, const uchar* _yuv)
|
|
2798 |
{
|
|
2799 |
YUV422i2RGB888Invoker<bIdx, uIdx, yIdx> converter(&_dst, _stride, _yuv);
|
|
2800 |
#ifdef HAVE_TBB
|
|
2801 |
if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION)
|
|
2802 |
parallel_for(BlockedRange(0, _dst.rows), converter);
|
|
2803 |
else
|
|
2804 |
#endif
|
|
2805 |
converter(BlockedRange(0, _dst.rows));
|
|
2806 |
}
|
|
2807 |
|
|
2808 |
template<int bIdx, int uIdx, int yIdx>
|
|
2809 |
inline void cvtYUV422i2RGBA(Mat& _dst, int _stride, const uchar* _yuv)
|
|
2810 |
{
|
|
2811 |
YUV422i2RGBA888Invoker<bIdx, uIdx, yIdx> converter(&_dst, _stride, _yuv);
|
|
2812 |
#ifdef HAVE_TBB
|
|
2813 |
if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV422_CONVERSION)
|
|
2814 |
parallel_for(BlockedRange(0, _dst.rows), converter);
|
|
2815 |
else
|
|
2816 |
#endif
|
|
2817 |
converter(BlockedRange(0, _dst.rows));
|
|
2818 |
}
|
|
2819 |
|
2668 |
2820 |
///////////////////////////////////// YUV420 -> RGB /////////////////////////////////////
|
2669 |
2821 |
|
2670 |
2822 |
template<int bIdx, int uIdx>
|
2671 |
|
struct YUV4202RGB888Invoker
|
|
2823 |
struct YUV420sp2RGB888Invoker
|
2672 |
2824 |
{
|
2673 |
2825 |
Mat* dst;
|
2674 |
2826 |
const uchar* my1, *muv;
|
2675 |
2827 |
int width, stride;
|
2676 |
2828 |
|
2677 |
|
YUV4202RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _uv)
|
|
2829 |
YUV420sp2RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _uv)
|
2678 |
2830 |
: dst(_dst), my1(_y1), muv(_uv), width(_dst->cols), stride(_stride) {}
|
2679 |
2831 |
|
2680 |
2832 |
void operator()(const BlockedRange& range) const
|
... | ... | |
2744 |
2896 |
};
|
2745 |
2897 |
|
2746 |
2898 |
template<int bIdx, int uIdx>
|
2747 |
|
struct YUV4202RGBA8888Invoker
|
|
2899 |
struct YUV420sp2RGBA8888Invoker
|
2748 |
2900 |
{
|
2749 |
2901 |
Mat* dst;
|
2750 |
2902 |
const uchar* my1, *muv;
|
2751 |
2903 |
int width, stride;
|
2752 |
2904 |
|
2753 |
|
YUV4202RGBA8888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _uv)
|
|
2905 |
YUV420sp2RGBA8888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _uv)
|
2754 |
2906 |
: dst(_dst), my1(_y1), muv(_uv), width(_dst->cols), stride(_stride) {}
|
2755 |
2907 |
|
2756 |
2908 |
void operator()(const BlockedRange& range) const
|
... | ... | |
2823 |
2975 |
}
|
2824 |
2976 |
};
|
2825 |
2977 |
|
|
2978 |
template<int bIdx>
|
|
2979 |
struct YUV420p2RGB888Invoker
|
|
2980 |
{
|
|
2981 |
Mat* dst;
|
|
2982 |
const uchar* my1, *mu, *mv;
|
|
2983 |
int width, stride;
|
|
2984 |
|
|
2985 |
YUV420p2RGB888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v)
|
|
2986 |
: dst(_dst), my1(_y1), mu(_u), mv(_v), width(_dst->cols), stride(_stride) {}
|
|
2987 |
|
|
2988 |
void operator()(const BlockedRange& range) const
|
|
2989 |
{
|
|
2990 |
int rangeBegin = range.begin() * 2;
|
|
2991 |
int rangeEnd = range.end() * 2;
|
|
2992 |
|
|
2993 |
//R = 1.164(Y - 16) + 1.596(V - 128)
|
|
2994 |
//G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
|
|
2995 |
//B = 1.164(Y - 16) + 2.018(U - 128)
|
|
2996 |
|
|
2997 |
//R = (1220542(Y - 16) + 1673527(V - 128) + (1 << 19)) >> 20
|
|
2998 |
//G = (1220542(Y - 16) - 852492(V - 128) - 409993(U - 128) + (1 << 19)) >> 20
|
|
2999 |
//B = (1220542(Y - 16) + 2116026(U - 128) + (1 << 19)) >> 20
|
|
3000 |
|
|
3001 |
const int cY = 1220542;
|
|
3002 |
const int cUB = 2116026;
|
|
3003 |
const int cUG = -409993;
|
|
3004 |
const int cVG = -852492;
|
|
3005 |
const int cVR = 1673527;
|
|
3006 |
const int YUV420_SHIFT = 20;
|
|
3007 |
|
|
3008 |
const uchar* y1 = my1 + rangeBegin * stride, *u1 = mu + rangeBegin * stride / 4, *v1 = mv + rangeBegin * stride / 4;
|
|
3009 |
|
|
3010 |
for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, u1 += stride / 2, v1 += stride / 2)
|
|
3011 |
{
|
|
3012 |
uchar* row1 = dst->ptr<uchar>(j);
|
|
3013 |
uchar* row2 = dst->ptr<uchar>(j + 1);
|
|
3014 |
const uchar* y2 = y1 + stride;
|
|
3015 |
|
|
3016 |
for (int i = 0; i < width / 2; i += 1, row1 += 6, row2 += 6)
|
|
3017 |
{
|
|
3018 |
int u = int(u1[i]) - 128;
|
|
3019 |
int v = int(v1[i]) - 128;
|
|
3020 |
|
|
3021 |
int ruv = (1 << (YUV420_SHIFT - 1)) + cVR * v;
|
|
3022 |
int guv = (1 << (YUV420_SHIFT - 1)) + cVG * v + cUG * u;
|
|
3023 |
int buv = (1 << (YUV420_SHIFT - 1)) + cUB * u;
|
|
3024 |
|
|
3025 |
int y00 = std::max(0, int(y1[2 * i]) - 16) * cY;
|
|
3026 |
row1[2-bIdx] = saturate_cast<uchar>((y00 + ruv) >> YUV420_SHIFT);
|
|
3027 |
row1[1] = saturate_cast<uchar>((y00 + guv) >> YUV420_SHIFT);
|
|
3028 |
row1[bIdx] = saturate_cast<uchar>((y00 + buv) >> YUV420_SHIFT);
|
|
3029 |
|
|
3030 |
int y01 = std::max(0, int(y1[2 * i + 1]) - 16) * cY;
|
|
3031 |
row1[5-bIdx] = saturate_cast<uchar>((y01 + ruv) >> YUV420_SHIFT);
|
|
3032 |
row1[4] = saturate_cast<uchar>((y01 + guv) >> YUV420_SHIFT);
|
|
3033 |
row1[3+bIdx] = saturate_cast<uchar>((y01 + buv) >> YUV420_SHIFT);
|
|
3034 |
|
|
3035 |
int y10 = std::max(0, int(y2[2 * i]) - 16) * cY;
|
|
3036 |
row2[2-bIdx] = saturate_cast<uchar>((y10 + ruv) >> YUV420_SHIFT);
|
|
3037 |
row2[1] = saturate_cast<uchar>((y10 + guv) >> YUV420_SHIFT);
|
|
3038 |
row2[bIdx] = saturate_cast<uchar>((y10 + buv) >> YUV420_SHIFT);
|
|
3039 |
|
|
3040 |
int y11 = std::max(0, int(y2[2 * i + 1]) - 16) * cY;
|
|
3041 |
row2[5-bIdx] = saturate_cast<uchar>((y11 + ruv) >> YUV420_SHIFT);
|
|
3042 |
row2[4] = saturate_cast<uchar>((y11 + guv) >> YUV420_SHIFT);
|
|
3043 |
row2[3+bIdx] = saturate_cast<uchar>((y11 + buv) >> YUV420_SHIFT);
|
|
3044 |
}
|
|
3045 |
|
|
3046 |
}
|
|
3047 |
}
|
|
3048 |
};
|
|
3049 |
|
|
3050 |
template<int bIdx>
|
|
3051 |
struct YUV420p2RGBA8888Invoker
|
|
3052 |
{
|
|
3053 |
Mat* dst;
|
|
3054 |
const uchar* my1, *mu, *mv;
|
|
3055 |
int width, stride;
|
|
3056 |
|
|
3057 |
YUV420p2RGBA8888Invoker(Mat* _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v)
|
|
3058 |
: dst(_dst), my1(_y1), mu(_u), mv(_v), width(_dst->cols), stride(_stride) {}
|
|
3059 |
|
|
3060 |
void operator()(const BlockedRange& range) const
|
|
3061 |
{
|
|
3062 |
int rangeBegin = range.begin() * 2;
|
|
3063 |
int rangeEnd = range.end() * 2;
|
|
3064 |
|
|
3065 |
//R = 1.164(Y - 16) + 1.596(V - 128)
|
|
3066 |
//G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
|
|
3067 |
//B = 1.164(Y - 16) + 2.018(U - 128)
|
|
3068 |
|
|
3069 |
//R = (1220542(Y - 16) + 1673527(V - 128) + (1 << 19)) >> 20
|
|
3070 |
//G = (1220542(Y - 16) - 852492(V - 128) - 409993(U - 128) + (1 << 19)) >> 20
|
|
3071 |
//B = (1220542(Y - 16) + 2116026(U - 128) + (1 << 19)) >> 20
|
|
3072 |
|
|
3073 |
const int cY = 1220542;
|
|
3074 |
const int cUB = 2116026;
|
|
3075 |
const int cUG = -409993;
|
|
3076 |
const int cVG = -852492;
|
|
3077 |
const int cVR = 1673527;
|
|
3078 |
const int YUV420_SHIFT = 20;
|
|
3079 |
|
|
3080 |
const uchar* y1 = my1 + rangeBegin * stride, *u1 = mu + rangeBegin * stride / 4, *v1 = mv + rangeBegin * stride / 4;
|
|
3081 |
|
|
3082 |
for (int j = rangeBegin; j < rangeEnd; j += 2, y1 += stride * 2, u1 += stride / 2, v1 += stride / 2)
|
|
3083 |
{
|
|
3084 |
uchar* row1 = dst->ptr<uchar>(j);
|
|
3085 |
uchar* row2 = dst->ptr<uchar>(j + 1);
|
|
3086 |
const uchar* y2 = y1 + stride;
|
|
3087 |
|
|
3088 |
for (int i = 0; i < width / 2; i += 1, row1 += 8, row2 += 8)
|
|
3089 |
{
|
|
3090 |
int u = int(u1[i]) - 128;
|
|
3091 |
int v = int(v1[i]) - 128;
|
|
3092 |
|
|
3093 |
int ruv = (1 << (YUV420_SHIFT - 1)) + cVR * v;
|
|
3094 |
int guv = (1 << (YUV420_SHIFT - 1)) + cVG * v + cUG * u;
|
|
3095 |
int buv = (1 << (YUV420_SHIFT - 1)) + cUB * u;
|
|
3096 |
|
|
3097 |
int y00 = std::max(0, int(y1[2 * i]) - 16) * cY;
|
|
3098 |
row1[2-bIdx] = saturate_cast<uchar>((y00 + ruv) >> YUV420_SHIFT);
|
|
3099 |
row1[1] = saturate_cast<uchar>((y00 + guv) >> YUV420_SHIFT);
|
|
3100 |
row1[bIdx] = saturate_cast<uchar>((y00 + buv) >> YUV420_SHIFT);
|
|
3101 |
row1[3] = uchar(0xff);
|
|
3102 |
|
|
3103 |
int y01 = std::max(0, int(y1[2 * i + 1]) - 16) * cY;
|
|
3104 |
row1[6-bIdx] = saturate_cast<uchar>((y01 + ruv) >> YUV420_SHIFT);
|
|
3105 |
row1[5] = saturate_cast<uchar>((y01 + guv) >> YUV420_SHIFT);
|
|
3106 |
row1[4+bIdx] = saturate_cast<uchar>((y01 + buv) >> YUV420_SHIFT);
|
|
3107 |
row1[7] = uchar(0xff);
|
|
3108 |
|
|
3109 |
int y10 = std::max(0, int(y2[2 * i]) - 16) * cY;
|
|
3110 |
row2[2-bIdx] = saturate_cast<uchar>((y10 + ruv) >> YUV420_SHIFT);
|
|
3111 |
row2[1] = saturate_cast<uchar>((y10 + guv) >> YUV420_SHIFT);
|
|
3112 |
row2[bIdx] = saturate_cast<uchar>((y10 + buv) >> YUV420_SHIFT);
|
|
3113 |
row2[3] = uchar(0xff);
|
|
3114 |
|
|
3115 |
int y11 = std::max(0, int(y2[2 * i + 1]) - 16) * cY;
|
|
3116 |
row2[6-bIdx] = saturate_cast<uchar>((y11 + ruv) >> YUV420_SHIFT);
|
|
3117 |
row2[5] = saturate_cast<uchar>((y11 + guv) >> YUV420_SHIFT);
|
|
3118 |
row2[4+bIdx] = saturate_cast<uchar>((y11 + buv) >> YUV420_SHIFT);
|
|
3119 |
row2[7] = uchar(0xff);
|
|
3120 |
}
|
|
3121 |
}
|
|
3122 |
}
|
|
3123 |
};
|
|
3124 |
|
2826 |
3125 |
#define MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION (320*240)
|
2827 |
3126 |
template<int bIdx, int uIdx>
|
2828 |
|
inline void cvtYUV4202RGB(Mat& _dst, int _stride, const uchar* _y1, const uchar* _uv)
|
|
3127 |
inline void cvtYUV420sp2RGB(Mat& _dst, int _stride, const uchar* _y1, const uchar* _uv)
|
2829 |
3128 |
{
|
2830 |
|
YUV4202RGB888Invoker<bIdx, uIdx> converter(&_dst, _stride, _y1, _uv);
|
|
3129 |
YUV420sp2RGB888Invoker<bIdx, uIdx> converter(&_dst, _stride, _y1, _uv);
|
2831 |
3130 |
#ifdef HAVE_TBB
|
2832 |
3131 |
if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION)
|
2833 |
3132 |
parallel_for(BlockedRange(0, _dst.rows/2), converter);
|
... | ... | |
2837 |
3136 |
}
|
2838 |
3137 |
|
2839 |
3138 |
template<int bIdx, int uIdx>
|
2840 |
|
inline void cvtYUV4202RGBA(Mat& _dst, int _stride, const uchar* _y1, const uchar* _uv)
|
|
3139 |
inline void cvtYUV420sp2RGBA(Mat& _dst, int _stride, const uchar* _y1, const uchar* _uv)
|
|
3140 |
{
|
|
3141 |
YUV420sp2RGBA8888Invoker<bIdx, uIdx> converter(&_dst, _stride, _y1, _uv);
|
|
3142 |
#ifdef HAVE_TBB
|
|
3143 |
if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION)
|
|
3144 |
parallel_for(BlockedRange(0, _dst.rows/2), converter);
|
|
3145 |
else
|
|
3146 |
#endif
|
|
3147 |
converter(BlockedRange(0, _dst.rows/2));
|
|
3148 |
}
|
|
3149 |
|
|
3150 |
template<int bIdx>
|
|
3151 |
inline void cvtYUV420p2RGB(Mat& _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v)
|
2841 |
3152 |
{
|
2842 |
|
YUV4202RGBA8888Invoker<bIdx, uIdx> converter(&_dst, _stride, _y1, _uv);
|
|
3153 |
YUV420p2RGB888Invoker<bIdx> converter(&_dst, _stride, _y1, _u, _v);
|
|
3154 |
#ifdef HAVE_TBB
|
|
3155 |
if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION)
|
|
3156 |
parallel_for(BlockedRange(0, _dst.rows/2), converter);
|
|
3157 |
else
|
|
3158 |
#endif
|
|
3159 |
converter(BlockedRange(0, _dst.rows/2));
|
|
3160 |
}
|
|
3161 |
|
|
3162 |
template<int bIdx>
|
|
3163 |
inline void cvtYUV420p2RGBA(Mat& _dst, int _stride, const uchar* _y1, const uchar* _u, const uchar* _v)
|
|
3164 |
{
|
|
3165 |
YUV420p2RGBA8888Invoker<bIdx> converter(&_dst, _stride, _y1, _u, _v);
|
2843 |
3166 |
#ifdef HAVE_TBB
|
2844 |
3167 |
if (_dst.total() >= MIN_SIZE_FOR_PARALLEL_YUV420_CONVERSION)
|
2845 |
3168 |
parallel_for(BlockedRange(0, _dst.rows/2), converter);
|
... | ... | |
3239 |
3562 |
if (CV_YUV420sp2RGB == code || COLOR_YUV420sp2RGBA == code)
|
3240 |
3563 |
{
|
3241 |
3564 |
if (dcn == 3)
|
3242 |
|
cvtYUV4202RGB<2, 1>(dst, srcstep, y, uv);
|
|
3565 |
cvtYUV420sp2RGB<2, 1>(dst, srcstep, y, uv);
|
3243 |
3566 |
else
|
3244 |
|
cvtYUV4202RGBA<2, 1>(dst, srcstep, y, uv);
|
|
3567 |
cvtYUV420sp2RGBA<2, 1>(dst, srcstep, y, uv);
|
3245 |
3568 |
}
|
3246 |
3569 |
else if (CV_YUV420sp2BGR == code || CV_YUV420sp2BGRA == code)
|
3247 |
3570 |
{
|
3248 |
3571 |
if (dcn == 3)
|
3249 |
|
cvtYUV4202RGB<0, 1>(dst, srcstep, y, uv);
|
|
3572 |
cvtYUV420sp2RGB<0, 1>(dst, srcstep, y, uv);
|
3250 |
3573 |
else
|
3251 |
|
cvtYUV4202RGBA<0, 1>(dst, srcstep, y, uv);
|
|
3574 |
cvtYUV420sp2RGBA<0, 1>(dst, srcstep, y, uv);
|
3252 |
3575 |
}
|
3253 |
3576 |
else if (CV_YUV2RGB_NV12 == code || CV_YUV2RGBA_NV12 == code)
|
3254 |
3577 |
{
|
3255 |
3578 |
if (dcn == 3)
|
3256 |
|
cvtYUV4202RGB<2, 0>(dst, srcstep, y, uv);
|
|
3579 |
cvtYUV420sp2RGB<2, 0>(dst, srcstep, y, uv);
|
3257 |
3580 |
else
|
3258 |
|
cvtYUV4202RGBA<2, 0>(dst, srcstep, y, uv);
|
|
3581 |
cvtYUV420sp2RGBA<2, 0>(dst, srcstep, y, uv);
|
3259 |
3582 |
}
|
3260 |
3583 |
else //if (CV_YUV2BGR_NV12 == code || CV_YUV2BGRA_NV12 == code)
|
3261 |
3584 |
{
|
3262 |
3585 |
if (dcn == 3)
|
3263 |
|
cvtYUV4202RGB<0, 0>(dst, srcstep, y, uv);
|
|
3586 |
cvtYUV420sp2RGB<0, 0>(dst, srcstep, y, uv);
|
|
3587 |
else
|
|
3588 |
cvtYUV420sp2RGBA<0, 0>(dst, srcstep, y, uv);
|
|
3589 |
}
|
|
3590 |
}
|
|
3591 |
break;
|
|
3592 |
case CV_YUV2BGR_YV12: case CV_YUV2RGB_YV12: case CV_YUV2BGRA_YV12: case CV_YUV2RGBA_YV12:
|
|
3593 |
case CV_YUV2RGB_IYUV: case CV_YUV2BGR_IYUV: case CV_YUV2RGBA_IYUV: case CV_YUV2BGRA_IYUV:
|
|
3594 |
{
|
|
3595 |
if (dcn <= 0) dcn = (code==CV_YUV2BGRA_YV12 || code==CV_YUV2RGBA_YV12 || code==CV_YUV2RGBA_IYUV || code==CV_YUV2BGRA_IYUV) ? 4 : 3;
|
|
3596 |
CV_Assert( dcn == 3 || dcn == 4 );
|
|
3597 |
CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U );
|
|
3598 |
|
|
3599 |
Size dstSz(sz.width, sz.height * 2 / 3);
|
|
3600 |
_dst.create(dstSz, CV_MAKETYPE(depth, dcn));
|
|
3601 |
dst = _dst.getMat();
|
|
3602 |
int srcstep = (int)src.step;
|
|
3603 |
|
|
3604 |
const uchar* y = src.ptr();
|
|
3605 |
const uchar* u = y + srcstep * dstSz.height;
|
|
3606 |
const uchar* v = u + (srcstep * dstSz.height / 4);
|
|
3607 |
|
|
3608 |
if (CV_YUV2BGR_YV12 == code || CV_YUV2BGRA_YV12 == code )
|
|
3609 |
{
|
|
3610 |
if (dcn == 3)
|
|
3611 |
cvtYUV420p2RGB<0>(dst, srcstep, y, v, u);
|
|
3612 |
else
|
|
3613 |
cvtYUV420p2RGBA<0>(dst,srcstep, y, v, u);
|
|
3614 |
}
|
|
3615 |
else if (CV_YUV2RGB_YV12 == code || CV_YUV2RGBA_YV12 == code)
|
|
3616 |
{
|
|
3617 |
if (dcn == 3)
|
|
3618 |
cvtYUV420p2RGB<2>(dst, srcstep, y, v, u);
|
|
3619 |
else
|
|
3620 |
cvtYUV420p2RGBA<2>(dst, srcstep, y, v, u);
|
|
3621 |
}
|
|
3622 |
else if (CV_YUV2RGB_IYUV == code || CV_YUV2RGBA_IYUV == code)
|
|
3623 |
{
|
|
3624 |
if (dcn == 3)
|
|
3625 |
cvtYUV420p2RGB<2>(dst, srcstep, y, u, v);
|
|
3626 |
else
|
|
3627 |
cvtYUV420p2RGBA<2>(dst, srcstep, y, u, v);
|
|
3628 |
}
|
|
3629 |
else // if (CV_YUV2BGR_IYUV == code || CV_YUV2BGRA_IYUV == code)
|
|
3630 |
{
|
|
3631 |
if (dcn == 3)
|
|
3632 |
cvtYUV420p2RGB<0>(dst, srcstep, y, u, v);
|
|
3633 |
else
|
|
3634 |
cvtYUV420p2RGBA<0>(dst, srcstep, y, u, v);
|
|
3635 |
}
|
|
3636 |
}
|
|
3637 |
break;
|
|
3638 |
case CV_YUV2RGB_YUYV: case CV_YUV2RGB_UYVY: case CV_YUV2RGB_YVYU: case CV_YUV2RGB_VYUY:
|
|
3639 |
case CV_YUV2BGR_YUYV: case CV_YUV2BGR_UYVY: case CV_YUV2BGR_YVYU: case CV_YUV2BGR_VYUY:
|
|
3640 |
case CV_YUV2RGBA_YUYV: case CV_YUV2RGBA_UYVY: case CV_YUV2RGBA_YVYU: case CV_YUV2RGBA_VYUY:
|
|
3641 |
case CV_YUV2BGRA_YUYV: case CV_YUV2BGRA_UYVY: case CV_YUV2BGRA_YVYU: case CV_YUV2BGRA_VYUY:
|
|
3642 |
{
|
|
3643 |
if (dcn <= 0) dcn = (
|
|
3644 |
CV_YUV2RGBA_YUYV==code || CV_YUV2RGBA_UYVY==code || CV_YUV2RGBA_YVYU==code || CV_YUV2RGBA_VYUY==code ||
|
|
3645 |
CV_YUV2BGRA_YUYV==code || CV_YUV2BGRA_UYVY==code || CV_YUV2BGRA_YVYU==code || CV_YUV2BGRA_VYUY==code) ? 4 : 3;
|
|
3646 |
CV_Assert( dcn == 3 || dcn == 4 );
|
|
3647 |
CV_Assert( sz.width % 4 == 0 && depth == CV_8U );
|
|
3648 |
|
|
3649 |
Size dstSz(sz.width / 2, sz.height);
|
|
3650 |
_dst.create(dstSz, CV_MAKETYPE(depth, dcn));
|
|
3651 |
dst = _dst.getMat();
|
|
3652 |
int srcstep = (int)src.step;
|
|
3653 |
|
|
3654 |
const uchar* yuv = src.ptr();
|
|
3655 |
|
|
3656 |
// http://www.fourcc.org/yuv.php#YUY2 ->
|
|
3657 |
if (CV_YUV2RGB_YUYV == code || CV_YUV2RGBA_YUYV == code)
|
|
3658 |
{
|
|
3659 |
if (dcn == 3)
|
|
3660 |
cvtYUV422i2RGB<2, 1, 0>(dst, srcstep, yuv);
|
|
3661 |
else
|
|
3662 |
cvtYUV422i2RGBA<2, 1, 0>(dst, srcstep, yuv);
|
|
3663 |
}
|
|
3664 |
// http://www.fourcc.org/yuv.php#YUY2 ->
|
|
3665 |
else if (CV_YUV2RGB_YVYU == code || CV_YUV2RGBA_YVYU == code)
|
|
3666 |
{
|
|
3667 |
if (dcn == 3)
|
|
3668 |
cvtYUV422i2RGB<2, 3, 0>(dst, srcstep, yuv);
|
|
3669 |
else
|
|
3670 |
cvtYUV422i2RGBA<2, 3, 0>(dst, srcstep, yuv);
|
|
3671 |
}
|
|
3672 |
// http://www.fourcc.org/yuv.php VYUY ->
|
|
3673 |
else if (CV_YUV2RGB_VYUY == code || CV_YUV2RGBA_VYUY == code)
|
|
3674 |
{
|
|
3675 |
if (dcn == 3)
|
|
3676 |
cvtYUV422i2RGB<2, 2, 1>(dst, srcstep, yuv);
|
|
3677 |
else
|
|
3678 |
cvtYUV422i2RGBA<2, 2, 1>(dst, srcstep, yuv);
|
|
3679 |
}
|
|
3680 |
// http://www.fourcc.org/yuv.php#Y422 ->
|
|
3681 |
else if (CV_YUV2RGB_UYVY == code || CV_YUV2RGBA_UYVY == code)
|
|
3682 |
{
|
|
3683 |
if (dcn == 3)
|
|
3684 |
cvtYUV422i2RGB<2, 0, 1>(dst, srcstep, yuv);
|
|
3685 |
else
|
|
3686 |
cvtYUV422i2RGBA<2, 0, 1>(dst, srcstep, yuv);
|
|
3687 |
}
|
|
3688 |
// http://www.fourcc.org/yuv.php#YUY2 ->
|
|
3689 |
else if (CV_YUV2BGR_YUYV == code || CV_YUV2BGRA_YUYV == code)
|
|
3690 |
{
|
|
3691 |
if (dcn == 3)
|
|
3692 |
cvtYUV422i2RGB<0, 1, 0>(dst, srcstep, yuv);
|
|
3693 |
else
|
|
3694 |
cvtYUV422i2RGBA<0, 1, 0>(dst, srcstep, yuv);
|
|
3695 |
}
|
|
3696 |
// http://www.fourcc.org/yuv.php#YUY2 ->
|
|
3697 |
else if (CV_YUV2BGR_YVYU == code || CV_YUV2BGRA_YVYU == code)
|
|
3698 |
{
|
|
3699 |
if (dcn == 3)
|
|
3700 |
cvtYUV422i2RGB<0, 3, 0>(dst, srcstep, yuv);
|
|
3701 |
else
|
|
3702 |
cvtYUV422i2RGBA<0, 3, 0>(dst, srcstep, yuv);
|
|
3703 |
}
|
|
3704 |
// http://www.fourcc.org/yuv.php VYUY ->
|
|
3705 |
else if (CV_YUV2BGR_VYUY == code || CV_YUV2BGRA_VYUY == code)
|
|
3706 |
{
|
|
3707 |
if (dcn == 3)
|
|
3708 |
cvtYUV422i2RGB<0, 2, 1>(dst, srcstep, yuv);
|
|
3709 |
else
|
|
3710 |
cvtYUV422i2RGBA<0, 2, 1>(dst, srcstep, yuv);
|
|
3711 |
}
|
|
3712 |
// http://www.fourcc.org/yuv.php#Y422 ->
|
|
3713 |
else // if (CV_YUV2BGR_UYVY == code || CV_YUV2BGRA_UYVY == code)
|
|
3714 |
{
|
|
3715 |
if (dcn == 3)
|
|
3716 |
cvtYUV422i2RGB<0, 0, 1>(dst, srcstep, yuv);
|
3264 |
3717 |
else
|
3265 |
|
cvtYUV4202RGBA<0, 0>(dst, srcstep, y, uv);
|
|
3718 |
cvtYUV422i2RGBA<0, 0, 1>(dst, srcstep, yuv);
|
3266 |
3719 |
}
|
3267 |
3720 |
}
|
3268 |
3721 |
break;
|