0003-Opencv_trunk_YUV_formats.patch

Patch adding YUV420p and YUV422i to RGB(A) conversion functions. - Robert Abel, 2012-03-30 06:10 pm

Download (26.5 kB)

 
b/opencv/modules/imgproc/include/opencv2/imgproc/imgproc.hpp 2012-03-30 10:19:33 +0200
929 914
    COLOR_YUV420sp2RGBA = COLOR_YUV2RGBA_NV21,
930 915
    COLOR_YUV420sp2BGRA = COLOR_YUV2BGRA_NV21,
931 916
    
932
    COLOR_COLORCVT_MAX  =100
917

  
918
    COLOR_YUV2RGB_YUYV  = 100,
919
    COLOR_YUV2BGR_YUYV  = 101,
920
    COLOR_YUV2RGB_UYVY  = 102,
921
    COLOR_YUV2BGR_UYVY  = 103,
922
    COLOR_YUV2RGB_YUY2  = COLOR_YUV2RGB_YUYV,
923
    COLOR_YUV2BGR_YUY2  = COLOR_YUV2BGR_YUYV,
924
    COLOR_YUV2RGB_VYUY  = 104,
925
    COLOR_YUV2BGR_VYUY  = 105,
926
    COLOR_YUV2RGB_YVYU  = 106,
927
    COLOR_YUV2BGR_YVYU  = 107,
928

  
929
    COLOR_YUV2RGBA_YUYV = 108,
930
    COLOR_YUV2BGRA_YUYV = 109,
931
    COLOR_YUV2RGBA_UYVY = 110,
932
    COLOR_YUV2BGRA_UYVY = 111,
933
    COLOR_YUV2RGBA_YUY2 = COLOR_YUV2RGBA_YUYV,
934
    COLOR_YUV2BGRA_YUY2 = COLOR_YUV2BGRA_YUYV,
935
    COLOR_YUV2RGBA_VYUY = 112,
936
    COLOR_YUV2BGRA_VYUY = 113,
937
    COLOR_YUV2RGBA_YVYU = 114,
938
    COLOR_YUV2BGRA_YVYU = 115,
939

  
940
    COLOR_YUV2RGB_YV12  = 116,
941
    COLOR_YUV2BGR_YV12  = 117,
942
    COLOR_YUV2RGB_IYUV  = 118,
943
    COLOR_YUV2BGR_IYUV  = 119,
944
    COLOR_YUV420p2RGB   = COLOR_YUV2RGB_YV12,
945
    COLOR_YUV420p2BGR   = COLOR_YUV2BGR_YV12,
946

  
947
    COLOR_YUV2RGBA_YV12 = 120,
948
    COLOR_YUV2BGRA_YV12 = 121,
949
    COLOR_YUV2RGBA_IYUV = 122,
950
    COLOR_YUV2BGRA_IYUV = 123,
951
    COLOR_YUV420p2RGBA  = COLOR_YUV2RGBA_YV12,
952
    COLOR_YUV420p2BGRA  = COLOR_YUV2BGRA_YV12,
953

  
954
    COLOR_COLORCVT_MAX  = 124
933 955
};
934 956
    
935 957
    
b/opencv/modules/imgproc/include/opencv2/imgproc/types_c.h 2012-03-30 10:16:03 +0200
232 240
    CV_YUV420sp2RGBA = CV_YUV2RGBA_NV21,
233 241
    CV_YUV420sp2BGRA = CV_YUV2BGRA_NV21,
234 242
    
235
    CV_COLORCVT_MAX  =100
243
    CV_YUV2RGB_YUYV  = 100,
244
    CV_YUV2BGR_YUYV  = 101,
245
    CV_YUV2RGB_UYVY  = 102,
246
    CV_YUV2BGR_UYVY  = 103,
247
    CV_YUV2RGB_YUY2  = CV_YUV2RGB_YUYV,
248
    CV_YUV2BGR_YUY2  = CV_YUV2BGR_YUYV,
249
    CV_YUV2RGB_VYUY  = 104,
250
    CV_YUV2BGR_VYUY  = 105,
251
    CV_YUV2RGB_YVYU  = 106,
252
    CV_YUV2BGR_YVYU  = 107,
253

  
254
    CV_YUV2RGBA_YUYV = 108,
255
    CV_YUV2BGRA_YUYV = 109,
256
    CV_YUV2RGBA_UYVY = 110,
257
    CV_YUV2BGRA_UYVY = 111,
258
    CV_YUV2RGBA_YUY2 = CV_YUV2RGBA_YUYV,
259
    CV_YUV2BGRA_YUY2 = CV_YUV2BGRA_YUYV,
260
    CV_YUV2RGBA_VYUY = 112,
261
    CV_YUV2BGRA_VYUY = 113,
262
    CV_YUV2RGBA_YVYU = 114,
263
    CV_YUV2BGRA_YVYU = 115,
264

  
265
    CV_YUV2RGB_YV12  = 116,
266
    CV_YUV2BGR_YV12  = 117,
267
    CV_YUV2RGB_IYUV  = 118,
268
    CV_YUV2BGR_IYUV  = 119,
269
    CV_YUV420p2RGB   = CV_YUV2RGB_YV12,
270
    CV_YUV420p2BGR   = CV_YUV2BGR_YV12,
271

  
272
    CV_YUV2RGBA_YV12 = 120,
273
    CV_YUV2BGRA_YV12 = 121,
274
    CV_YUV2RGBA_IYUV = 122,
275
    CV_YUV2BGRA_IYUV = 123,
276
    CV_YUV420p2RGBA  = CV_YUV2RGBA_YV12,
277
    CV_YUV420p2BGRA  = CV_YUV2BGRA_YV12,
278

  
279
    CV_COLORCVT_MAX  = 124
236 280
};
237 281

  
238 282

  
b/opencv/modules/imgproc/src/color.cpp 2012-03-30 10:11:48 +0200
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;