added 16-bit support to Bayer2RGB & Bayer2Gray (ticket #686); fixed bug in cv.CreateH...
authorVadim Pisarevsky <no@email>
Fri, 3 Jun 2011 15:45:50 +0000 (15:45 +0000)
committerVadim Pisarevsky <no@email>
Fri, 3 Jun 2011 15:45:50 +0000 (15:45 +0000)
modules/imgproc/src/color.cpp
modules/imgproc/test/test_main.cpp
modules/python/src1/cv.cpp

index 6d51b01..bf65a31 100644 (file)
@@ -1725,24 +1725,182 @@ struct Luv2RGB_b
         
 //////////////////////////// Bayer Pattern -> RGB conversion /////////////////////////////
 
-static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code )
+template<typename T>
+class SIMDBayerStubInterpolator_
 {
+public:
+    int bayer2Gray(const T*, int, T*, int, int, int, int) const
+    {
+        return 0;
+    }
+    
+    int bayer2RGB(const T*, int, T*, int, int) const
+    {
+        return 0;
+    }
+};    
+    
+#if CV_SSE2
+class SIMDBayerInterpolator_8u
+{
+public:
+    SIMDBayerInterpolator_8u()
+    {
+        use_simd = checkHardwareSupport(CV_CPU_SSE2);
+    }
+    
+    int bayer2Gray(const uchar* bayer, int bayer_step, uchar* dst,
+                   int width, int bcoeff, int gcoeff, int rcoeff) const
+    {
+        if( !use_simd )
+            return 0;
+        
+        __m128i _b2y = _mm_set1_epi16((short)(rcoeff*2));
+        __m128i _g2y = _mm_set1_epi16((short)(gcoeff*2));
+        __m128i _r2y = _mm_set1_epi16((short)(bcoeff*2));
+        const uchar* bayer_end = bayer + width;
+        
+        for( ; bayer <= bayer_end - 18; bayer += 14, dst += 14 )
+        {
+            __m128i r0 = _mm_loadu_si128((const __m128i*)bayer);
+            __m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step));
+            __m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2));
+            
+            __m128i b1 = _mm_add_epi16(_mm_srli_epi16(_mm_slli_epi16(r0, 8), 8),
+                                       _mm_srli_epi16(_mm_slli_epi16(r2, 8), 8));
+            __m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2));
+            b1 = _mm_slli_epi16(_mm_srli_si128(b1, 2), 1);
+            
+            __m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 8), _mm_srli_epi16(r2, 8));
+            __m128i g1 = _mm_srli_epi16(_mm_slli_epi16(r1, 8), 8);
+            g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2)));
+            g1 = _mm_slli_epi16(_mm_srli_si128(g1, 2), 2);
+            
+            r0 = _mm_srli_epi16(r1, 8);
+            r1 = _mm_slli_epi16(_mm_add_epi16(r0, _mm_srli_si128(r0, 2)), 1);
+            r0 = _mm_slli_epi16(r0, 2);
+            
+            g0 = _mm_add_epi16(_mm_mulhi_epi16(b0, _b2y), _mm_mulhi_epi16(g0, _g2y));
+            g1 = _mm_add_epi16(_mm_mulhi_epi16(b1, _b2y), _mm_mulhi_epi16(g1, _g2y));
+            g0 = _mm_add_epi16(g0, _mm_mulhi_epi16(r0, _r2y));
+            g1 = _mm_add_epi16(g1, _mm_mulhi_epi16(r1, _r2y));
+            g0 = _mm_srli_epi16(g0, 1);
+            g1 = _mm_srli_epi16(g1, 1);
+            g0 = _mm_packus_epi16(g0, g0);
+            g1 = _mm_packus_epi16(g1, g1);
+            g0 = _mm_unpacklo_epi8(g0, g1);
+            _mm_storeu_si128((__m128i*)dst, g0);
+        }
+        
+        return (int)(bayer - (bayer_end - width));
+    }
+    
+    int bayer2RGB(const uchar* bayer, int bayer_step, uchar* dst, int width, int blue) const
+    {
+        if( !use_simd )
+            return 0;
+        /*
+         B G B G | B G B G | B G B G | B G B G
+         G R G R | G R G R | G R G R | G R G R
+         B G B G | B G B G | B G B G | B G B G
+         */
+        __m128i delta1 = _mm_set1_epi16(1), delta2 = _mm_set1_epi16(2);
+        __m128i mask = _mm_set1_epi16(blue < 0 ? -1 : 0), z = _mm_setzero_si128();
+        __m128i masklo = _mm_set1_epi16(0x00ff);
+        const uchar* bayer_end = bayer + width;
+        
+        for( ; bayer <= bayer_end - 18; bayer += 14, dst += 42 )
+        {
+            __m128i r0 = _mm_loadu_si128((const __m128i*)bayer);
+            __m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step));
+            __m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2));
+            
+            __m128i b1 = _mm_add_epi16(_mm_and_si128(r0, masklo), _mm_and_si128(r2, masklo));
+            __m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2));
+            b1 = _mm_srli_si128(b1, 2);
+            b1 = _mm_srli_epi16(_mm_add_epi16(b1, delta1), 1);
+            b0 = _mm_srli_epi16(_mm_add_epi16(b0, delta2), 2);
+            b0 = _mm_packus_epi16(b0, b1);
+            
+            __m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 8), _mm_srli_epi16(r2, 8));
+            __m128i g1 = _mm_and_si128(r1, masklo);
+            g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2)));
+            g1 = _mm_srli_si128(g1, 2);
+            g0 = _mm_srli_epi16(_mm_add_epi16(g0, delta2), 2);
+            g0 = _mm_packus_epi16(g0, g1);
+            
+            r0 = _mm_srli_epi16(r1, 8);
+            r1 = _mm_add_epi16(r0, _mm_srli_si128(r0, 2));
+            r1 = _mm_srli_epi16(_mm_add_epi16(r1, delta1), 1);
+            r0 = _mm_packus_epi16(r0, r1);
+            
+            b1 = _mm_and_si128(_mm_xor_si128(b0, r0), mask);
+            b0 = _mm_xor_si128(b0, b1);
+            r0 = _mm_xor_si128(r0, b1);
+            
+            // b1 g1 b1 g1 ...
+            b1 = _mm_unpackhi_epi8(b0, g0);
+            // b0 g0 b2 g2 b4 g4 ....
+            b0 = _mm_unpacklo_epi8(b0, g0);
+            
+            // r1 0 r3 0 ...
+            r1 = _mm_unpackhi_epi8(r0, z);
+            // r0 0 r2 0 r4 0 ...
+            r0 = _mm_unpacklo_epi8(r0, z);
+            
+            // 0 b0 g0 r0 0 b2 g2 r2 0 ...
+            g0 = _mm_slli_si128(_mm_unpacklo_epi16(b0, r0), 1);
+            // 0 b8 g8 r8 0 b10 g10 r10 0 ...
+            g1 = _mm_slli_si128(_mm_unpackhi_epi16(b0, r0), 1);
+            
+            // b1 g1 r1 0 b3 g3 r3 ....
+            r0 = _mm_unpacklo_epi16(b1, r1);
+            // b9 g9 r9 0 ...
+            r1 = _mm_unpackhi_epi16(b1, r1);
+            
+            b0 = _mm_srli_si128(_mm_unpacklo_epi32(g0, r0), 1);
+            b1 = _mm_srli_si128(_mm_unpackhi_epi32(g0, r0), 1);
+            
+            _mm_storel_epi64((__m128i*)(dst-1+0), b0);
+            _mm_storel_epi64((__m128i*)(dst-1+6*1), _mm_srli_si128(b0, 8));
+            _mm_storel_epi64((__m128i*)(dst-1+6*2), b1);
+            _mm_storel_epi64((__m128i*)(dst-1+6*3), _mm_srli_si128(b1, 8));
+            
+            g0 = _mm_srli_si128(_mm_unpacklo_epi32(g1, r1), 1);
+            g1 = _mm_srli_si128(_mm_unpackhi_epi32(g1, r1), 1);
+            
+            _mm_storel_epi64((__m128i*)(dst-1+6*4), g0);
+            _mm_storel_epi64((__m128i*)(dst-1+6*5), _mm_srli_si128(g0, 8));
+            
+            _mm_storel_epi64((__m128i*)(dst-1+6*6), g1);
+        }
+        
+        return (int)(bayer - (bayer_end - width));
+    }
+    
+    bool use_simd;
+};
+#else
+typedef SIMDBayerStubInterpolator_<uchar> SIMDBayerInterpolator_8u;
+#endif
+    
+template<typename T, class SIMDInterpolator>
+static void Bayer2Gray_( const Mat& srcmat, Mat& dstmat, int code )
+{
+    SIMDInterpolator vecOp;
     const int R2Y = 4899;
     const int G2Y = 9617;
     const int B2Y = 1868;
     const int SHIFT = 14;
     
-    const uchar* bayer0 = srcmat.data;
-    int bayer_step = (int)srcmat.step;
-    uchar* dst0 = dstmat.data;
-    int dst_step = (int)dstmat.step;
+    const T* bayer0 = (const T*)srcmat.data;
+    int bayer_step = (int)(srcmat.step/sizeof(T));
+    T* dst0 = (T*)dstmat.data;
+    int dst_step = (int)(dstmat.step/sizeof(T));
     Size size = srcmat.size();
     int bcoeff = B2Y, rcoeff = R2Y;
     int start_with_green = code == CV_BayerGB2GRAY || code == CV_BayerGR2GRAY;
     bool brow = true;
-#if CV_SSE2    
-    bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2);
-#endif
     
     if( code != CV_BayerBG2GRAY && code != CV_BayerGB2GRAY )
     {
@@ -1756,10 +1914,10 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code )
     
     for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step )
     {
-        int t0, t1, t2;
-        const uchar* bayer = bayer0;
-        uchar* dst = dst0;
-        const uchar* bayer_end = bayer + size.width;
+        unsigned t0, t1, t2;
+        const T* bayer = bayer0;
+        T* dst = dst0;
+        const T* bayer_end = bayer + size.width;
         
         if( size.width <= 0 )
         {
@@ -1773,63 +1931,26 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code )
             t1 = (bayer[bayer_step] + bayer[bayer_step+2])*bcoeff;
             t2 = bayer[bayer_step+1]*(2*G2Y);
             
-            dst[0] = (uchar)CV_DESCALE(t0 + t1 + t2, SHIFT+1);
+            dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+1);
             bayer++;
             dst++;
         }
         
-#if CV_SSE2
-        if( haveSSE2 )
-        {
-            __m128i _b2y = _mm_set1_epi16((short)(rcoeff*2));
-            __m128i _g2y = _mm_set1_epi16((short)(G2Y*2));
-            __m128i _r2y = _mm_set1_epi16((short)(bcoeff*2));
-            
-            for( ; bayer <= bayer_end - 18; bayer += 14, dst += 14 )
-            {
-                __m128i r0 = _mm_loadu_si128((const __m128i*)bayer);
-                __m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step));
-                __m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2));
-                
-                __m128i b1 = _mm_add_epi16(_mm_srli_epi16(_mm_slli_epi16(r0, 8), 8),
-                                           _mm_srli_epi16(_mm_slli_epi16(r2, 8), 8));
-                __m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2));
-                b1 = _mm_slli_epi16(_mm_srli_si128(b1, 2), 1);
-                
-                __m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 8), _mm_srli_epi16(r2, 8));
-                __m128i g1 = _mm_srli_epi16(_mm_slli_epi16(r1, 8), 8);
-                g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2)));
-                g1 = _mm_slli_epi16(_mm_srli_si128(g1, 2), 2);
-                
-                r0 = _mm_srli_epi16(r1, 8);
-                r1 = _mm_slli_epi16(_mm_add_epi16(r0, _mm_srli_si128(r0, 2)), 1);
-                r0 = _mm_slli_epi16(r0, 2);
-                
-                g0 = _mm_add_epi16(_mm_mulhi_epi16(b0, _b2y), _mm_mulhi_epi16(g0, _g2y));
-                g1 = _mm_add_epi16(_mm_mulhi_epi16(b1, _b2y), _mm_mulhi_epi16(g1, _g2y));
-                g0 = _mm_add_epi16(g0, _mm_mulhi_epi16(r0, _r2y));
-                g1 = _mm_add_epi16(g1, _mm_mulhi_epi16(r1, _r2y));
-                g0 = _mm_srli_epi16(g0, 1);
-                g1 = _mm_srli_epi16(g1, 1);
-                g0 = _mm_packus_epi16(g0, g0);
-                g1 = _mm_packus_epi16(g1, g1);
-                g0 = _mm_unpacklo_epi8(g0, g1);
-                _mm_storeu_si128((__m128i*)dst, g0);
-            }
-        }
-#endif
+        int delta = vecOp.bayer2Gray(bayer, bayer_step, dst, size.width, bcoeff, G2Y, rcoeff);
+        bayer += delta;
+        dst += delta;
         
         for( ; bayer <= bayer_end - 2; bayer += 2, dst += 2 )
         {
             t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2])*rcoeff;
             t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1])*G2Y;
             t2 = bayer[bayer_step+1]*(4*bcoeff);
-            dst[0] = (uchar)CV_DESCALE(t0 + t1 + t2, SHIFT+2);
+            dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+2);
             
             t0 = (bayer[2] + bayer[bayer_step*2+2])*rcoeff;
             t1 = (bayer[bayer_step+1] + bayer[bayer_step+3])*bcoeff;
             t2 = bayer[bayer_step+2]*(2*G2Y);
-            dst[1] = (uchar)CV_DESCALE(t0 + t1 + t2, SHIFT+1);
+            dst[1] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+1);
         }
         
         if( bayer < bayer_end )
@@ -1837,7 +1958,7 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code )
             t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2])*rcoeff;
             t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1])*G2Y;
             t2 = bayer[bayer_step+1]*(4*bcoeff);
-            dst[0] = (uchar)CV_DESCALE(t0 + t1 + t2, SHIFT+2);
+            dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+2);
             bayer++;
             dst++;
         }
@@ -1851,7 +1972,7 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code )
     }
     
     size = dstmat.size();
-    dst0 = dstmat.data;
+    dst0 = (T*)dstmat.data;
     if( size.height > 2 )
         for( int i = 0; i < size.width; i++ )
         {
@@ -1865,19 +1986,17 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code )
         }
 }
 
-
-static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code )
+template<typename T, class SIMDInterpolator>    
+static void Bayer2RGB_( const Mat& srcmat, Mat& dstmat, int code )
 {
-    const uchar* bayer0 = srcmat.data;
-    int bayer_step = (int)srcmat.step;
-    uchar* dst0 = dstmat.data;
-    int dst_step = (int)dstmat.step;
+    SIMDInterpolator vecOp;
+    const T* bayer0 = (const T*)srcmat.data;
+    int bayer_step = (int)(srcmat.step/sizeof(T));
+    T* dst0 = (T*)dstmat.data;
+    int dst_step = (int)(dstmat.step/sizeof(T));
     Size size = srcmat.size();
     int blue = code == CV_BayerBG2BGR || code == CV_BayerGB2BGR ? -1 : 1;
     int start_with_green = code == CV_BayerGB2BGR || code == CV_BayerGR2BGR;
-#if CV_SSE2
-    bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2);
-#endif
     
     dst0 += dst_step + 3 + 1;
     size.height -= 2;
@@ -1886,9 +2005,9 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code )
     for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step )
     {
         int t0, t1;
-        const uchar* bayer = bayer0;
-        uchar* dst = dst0;
-        const uchar* bayer_end = bayer + size.width;
+        const T* bayer = bayer0;
+        T* dst = dst0;
+        const T* bayer_end = bayer + size.width;
         
         if( size.width <= 0 )
         {
@@ -1901,93 +2020,17 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code )
         {
             t0 = (bayer[1] + bayer[bayer_step*2+1] + 1) >> 1;
             t1 = (bayer[bayer_step] + bayer[bayer_step+2] + 1) >> 1;
-            dst[-blue] = (uchar)t0;
+            dst[-blue] = (T)t0;
             dst[0] = bayer[bayer_step+1];
-            dst[blue] = (uchar)t1;
+            dst[blue] = (T)t1;
             bayer++;
             dst += 3;
         }
         
-#if CV_SSE2
-        if( haveSSE2 )
-        {
-            /*
-             B G B G | B G B G | B G B G | B G B G
-             G R G R | G R G R | G R G R | G R G R
-             B G B G | B G B G | B G B G | B G B G
-             */
-            __m128i delta1 = _mm_set1_epi16(1), delta2 = _mm_set1_epi16(2);
-            __m128i mask = _mm_set1_epi16(blue < 0 ? -1 : 0), z = _mm_setzero_si128();
-            __m128i masklo = _mm_set1_epi16(0x00ff);
-            
-            for( ; bayer <= bayer_end - 18; bayer += 14, dst += 42 )
-            {
-                __m128i r0 = _mm_loadu_si128((const __m128i*)bayer);
-                __m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step));
-                __m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2));
-                
-                __m128i b1 = _mm_add_epi16(_mm_and_si128(r0, masklo), _mm_and_si128(r2, masklo));
-                __m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2));
-                b1 = _mm_srli_si128(b1, 2);
-                b1 = _mm_srli_epi16(_mm_add_epi16(b1, delta1), 1);
-                b0 = _mm_srli_epi16(_mm_add_epi16(b0, delta2), 2);
-                b0 = _mm_packus_epi16(b0, b1);
-                
-                __m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 8), _mm_srli_epi16(r2, 8));
-                __m128i g1 = _mm_and_si128(r1, masklo);
-                g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2)));
-                g1 = _mm_srli_si128(g1, 2);
-                g0 = _mm_srli_epi16(_mm_add_epi16(g0, delta2), 2);
-                g0 = _mm_packus_epi16(g0, g1);
-                
-                r0 = _mm_srli_epi16(r1, 8);
-                r1 = _mm_add_epi16(r0, _mm_srli_si128(r0, 2));
-                r1 = _mm_srli_epi16(_mm_add_epi16(r1, delta1), 1);
-                r0 = _mm_packus_epi16(r0, r1);
-                
-                b1 = _mm_and_si128(_mm_xor_si128(b0, r0), mask);
-                b0 = _mm_xor_si128(b0, b1);
-                r0 = _mm_xor_si128(r0, b1);
-                
-                // b1 g1 b1 g1 ...
-                b1 = _mm_unpackhi_epi8(b0, g0);
-                // b0 g0 b2 g2 b4 g4 ....
-                b0 = _mm_unpacklo_epi8(b0, g0);
-                
-                // r1 0 r3 0 ...
-                r1 = _mm_unpackhi_epi8(r0, z);
-                // r0 0 r2 0 r4 0 ...
-                r0 = _mm_unpacklo_epi8(r0, z);
-                
-                // 0 b0 g0 r0 0 b2 g2 r2 0 ...
-                g0 = _mm_slli_si128(_mm_unpacklo_epi16(b0, r0), 1);
-                // 0 b8 g8 r8 0 b10 g10 r10 0 ...
-                g1 = _mm_slli_si128(_mm_unpackhi_epi16(b0, r0), 1);
-                
-                // b1 g1 r1 0 b3 g3 r3 ....
-                r0 = _mm_unpacklo_epi16(b1, r1);
-                // b9 g9 r9 0 ...
-                r1 = _mm_unpackhi_epi16(b1, r1);
-                
-                b0 = _mm_srli_si128(_mm_unpacklo_epi32(g0, r0), 1);
-                b1 = _mm_srli_si128(_mm_unpackhi_epi32(g0, r0), 1);
+        int delta = vecOp.bayer2RGB(bayer, bayer_step, dst, size.width, blue);
+        bayer += delta;
+        dst += delta*3;
                 
-                _mm_storel_epi64((__m128i*)(dst-1+0), b0);
-                _mm_storel_epi64((__m128i*)(dst-1+6*1), _mm_srli_si128(b0, 8));
-                _mm_storel_epi64((__m128i*)(dst-1+6*2), b1);
-                _mm_storel_epi64((__m128i*)(dst-1+6*3), _mm_srli_si128(b1, 8));
-                
-                g0 = _mm_srli_si128(_mm_unpacklo_epi32(g1, r1), 1);
-                g1 = _mm_srli_si128(_mm_unpackhi_epi32(g1, r1), 1);
-                
-                _mm_storel_epi64((__m128i*)(dst-1+6*4), g0);
-                _mm_storel_epi64((__m128i*)(dst-1+6*5), _mm_srli_si128(g0, 8));
-                
-                _mm_storel_epi64((__m128i*)(dst-1+6*6), g1);
-            }
-        }
-#endif
-        
         if( blue > 0 )
         {
             for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 )
@@ -1996,15 +2039,15 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code )
                       bayer[bayer_step*2+2] + 2) >> 2;
                 t1 = (bayer[1] + bayer[bayer_step] +
                       bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2;
-                dst[-1] = (uchar)t0;
-                dst[0] = (uchar)t1;
+                dst[-1] = (T)t0;
+                dst[0] = (T)t1;
                 dst[1] = bayer[bayer_step+1];
                 
                 t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1;
                 t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1;
-                dst[2] = (uchar)t0;
+                dst[2] = (T)t0;
                 dst[3] = bayer[bayer_step+2];
-                dst[4] = (uchar)t1;
+                dst[4] = (T)t1;
             }
         }
         else
@@ -2015,15 +2058,15 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code )
                       bayer[bayer_step*2+2] + 2) >> 2;
                 t1 = (bayer[1] + bayer[bayer_step] +
                       bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2;
-                dst[1] = (uchar)t0;
-                dst[0] = (uchar)t1;
+                dst[1] = (T)t0;
+                dst[0] = (T)t1;
                 dst[-1] = bayer[bayer_step+1];
                 
                 t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1;
                 t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1;
-                dst[4] = (uchar)t0;
+                dst[4] = (T)t0;
                 dst[3] = bayer[bayer_step+2];
-                dst[2] = (uchar)t1;
+                dst[2] = (T)t1;
             }
         }
         
@@ -2033,8 +2076,8 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code )
                   bayer[bayer_step*2+2] + 2) >> 2;
             t1 = (bayer[1] + bayer[bayer_step] +
                   bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2;
-            dst[-blue] = (uchar)t0;
-            dst[0] = (uchar)t1;
+            dst[-blue] = (T)t0;
+            dst[0] = (T)t1;
             dst[blue] = bayer[bayer_step+1];
             bayer++;
             dst += 3;
@@ -2052,7 +2095,7 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code )
     }
     
     size = dstmat.size();
-    dst0 = dstmat.data;
+    dst0 = (T*)dstmat.data;
     if( size.height > 2 )
         for( int i = 0; i < size.width*3; i++ )
         {
@@ -2083,7 +2126,7 @@ static void Bayer2RGB_VNG_8u( const Mat& srcmat, Mat& dstmat, int code )
     // for too small images use the simple interpolation algorithm
     if( MIN(size.width, size.height) < 8 )
     {
-        Bayer2RGB_8u( srcmat, dstmat, code );
+        Bayer2RGB_<uchar, SIMDBayerInterpolator_8u>( srcmat, dstmat, code );
         return;
     }
     
@@ -2912,27 +2955,42 @@ void cv::cvtColor( const InputArray& _src, OutputArray _dst, int code, int dcn )
         
         case CV_BayerBG2GRAY: case CV_BayerGB2GRAY: case CV_BayerRG2GRAY: case CV_BayerGR2GRAY:
             if(dcn <= 0) dcn = 1;
-            CV_Assert( scn == 1 && dcn == 1 && depth == CV_8U );
+            CV_Assert( scn == 1 && dcn == 1 );
             
             _dst.create(sz, depth);
             dst = _dst.getMat();
             
-            Bayer2Gray_8u(src, dst, code);
-            break;    
+            if( depth == CV_8U )
+                Bayer2Gray_<uchar, SIMDBayerInterpolator_8u>(src, dst, code);
+            else if( depth == CV_16U )
+                Bayer2Gray_<ushort, SIMDBayerStubInterpolator_<ushort> >(src, dst, code);
+            else
+                CV_Error(CV_StsUnsupportedFormat, "Bayer->Gray demosaicing only supports 8u and 16u types");
+            break;
             
         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:
             if(dcn <= 0) dcn = 3;
-            CV_Assert( scn == 1 && dcn == 3 && depth == CV_8U );
+            CV_Assert( scn == 1 && dcn == 3 );
             
             _dst.create(sz, CV_MAKETYPE(depth, dcn));
             dst = _dst.getMat();
             
             if( code == CV_BayerBG2BGR || code == CV_BayerGB2BGR ||
                 code == CV_BayerRG2BGR || code == CV_BayerGR2BGR )
-                Bayer2RGB_8u(src, dst, code);
+            {
+                if( depth == CV_8U )
+                    Bayer2RGB_<uchar, SIMDBayerInterpolator_8u>(src, dst, code);
+                else if( depth == CV_16U )
+                    Bayer2RGB_<ushort, SIMDBayerStubInterpolator_<ushort> >(src, dst, code);
+                else
+                    CV_Error(CV_StsUnsupportedFormat, "Bayer->RGB demosaicing only supports 8u and 16u types");
+            }
             else
+            {
+                CV_Assert( depth == CV_8U );
                 Bayer2RGB_VNG_8u(src, dst, code);
+            }
             break;
         default:
             CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" );
index 15fd135..6b24993 100644 (file)
@@ -1,38 +1,3 @@
 #include "test_precomp.hpp"
 
 CV_TEST_MAIN("cv")
-
-#if 0
-using namespace cv;
-using namespace std;
-
-int main(int, char**)
-{
-#if 0
-    Mat src = imread("/Users/vp/Downloads/resize/original.png"), dst;
-    //resize(src, dst, Size(), 0.25, 0.25, INTER_NEAREST);
-    //imwrite("/Users/vp/Downloads/resize/xnview_nn_opencv.png", dst);
-    printf("\n\n\n\n\n\n***************************************\n");
-    //resize(src, dst, Size(), 0.25, 0.25, INTER_AREA);
-    //int nsteps = 4;
-    //double rate = pow(0.25,1./nsteps);
-    //for( int i = 0; i < nsteps; i++ )
-    //    resize(src, src, Size(), rate, rate, INTER_LINEAR );
-    //GaussianBlur(src, src, Size(5, 5), 2, 2);
-    resize(src, src, Size(), 0.25, 0.25, INTER_NEAREST);
-    imwrite("/Users/vp/Downloads/resize/xnview_bilinear_opencv.png", src);
-    //resize(src, dst, Size(), 0.25, 0.25, INTER_LANCZOS4);
-    //imwrite("/Users/vp/Downloads/resize/xnview_lanczos3_opencv.png", dst);
-#else
-    float data[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24};
-    Mat src(5,5,CV_32FC1, data);
-    Mat dst;
-    resize(src, dst, Size(), 3, 3, INTER_NEAREST); 
-    cout << src << endl;
-    cout << dst << endl;
-#endif
-    return 0;
-}
-#endif
-
-
index 7a65891..283a43f 100644 (file)
@@ -2965,16 +2965,20 @@ static PyObject *pycvCreateHist(PyObject *self, PyObject *args, PyObject *kw)
   }
   cvhistogram_t *h = PyObject_NEW(cvhistogram_t, &cvhistogram_Type);
   args = Py_BuildValue("Oi", dims, CV_32FC1);
+  memset(&h->h, 0, sizeof(h->h));
   h->bins = pycvCreateMatND(self, args);
   Py_DECREF(args);
   if (h->bins == NULL) {
     return NULL;
   }
-  h->h.type = CV_HIST_MAGIC_VAL;
+  h->h.type = CV_HIST_MAGIC_VAL + CV_HIST_UNIFORM_FLAG;
   if (!convert_to_CvArr(h->bins, &(h->h.bins), "bins"))
     return NULL;
 
-  ERRWRAP(cvSetHistBinRanges(&(h->h), r.rr, uniform));
+  if(r.rr)
+  {
+      ERRWRAP(cvSetHistBinRanges(&(h->h), r.rr, uniform));
+  }
 
   return (PyObject*)h;
 }