{"action":"opened","issue":{"url":"https://api.github.com/repos/Itseez/opencv/issues/5084","labels_url":"https://api.github.com/repos/Itseez/opencv/issues/5084/labels{/name}","comments_url":"https://api.github.com/repos/Itseez/opencv/issues/5084/comments","events_url":"https://api.github.com/repos/Itseez/opencv/issues/5084/events","html_url":"https://github.com/Itseez/opencv/issues/5084","id":97909828,"number":5084,"title":"Possible error in prefilterXSobel","user":{"login":"Grandgarfield","id":11198174,"avatar_url":"https://avatars.githubusercontent.com/u/11198174?v=3","gravatar_id":"","url":"https://api.github.com/users/Grandgarfield","html_url":"https://github.com/Grandgarfield","followers_url":"https://api.github.com/users/Grandgarfield/followers","following_url":"https://api.github.com/users/Grandgarfield/following{/other_user}","gists_url":"https://api.github.com/users/Grandgarfield/gists{/gist_id}","starred_url":"https://api.github.com/users/Grandgarfield/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Grandgarfield/subscriptions","organizations_url":"https://api.github.com/users/Grandgarfield/orgs","repos_url":"https://api.github.com/users/Grandgarfield/repos","events_url":"https://api.github.com/users/Grandgarfield/events{/privacy}","received_events_url":"https://api.github.com/users/Grandgarfield/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-07-29T10:42:22Z","updated_at":"2015-07-29T10:42:22Z","closed_at":null,"body":"Hi, \r\n\r\nI am currently working on stereo algorithm for my work and I noticed something strange in the function prefilterXSobel implementation in opencv/src/modules/calib3d/src/stereobm.cpp.\r\n\r\nThe function uses SSE2 and NEON instructions set to get better performances. But it seems to me that the code will go through the unoptimized loop even after SSE2 or neon part. A \"else\" is missing I think.\r\nStarting at line 194 I would correct the code like this, am I right or did I misunderstand the code ? \r\n\r\n#if CV_SSE2\r\n        if( useSIMD )\r\n        {\r\n            __m128i z = _mm_setzero_si128(), ftz = _mm_set1_epi16((short)ftzero),\r\n                ftz2 = _mm_set1_epi8(CV_CAST_8U(ftzero*2));\r\n            for( ; x <= size.width-9; x += 8 )\r\n            {\r\n                __m128i c0 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow0 + x - 1)), z);\r\n                __m128i c1 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow1 + x - 1)), z);\r\n                __m128i d0 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow0 + x + 1)), z);\r\n                __m128i d1 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow1 + x + 1)), z);\r\n\r\n                d0 = _mm_sub_epi16(d0, c0);\r\n                d1 = _mm_sub_epi16(d1, c1);\r\n\r\n                __m128i c2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x - 1)), z);\r\n                __m128i c3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow3 + x - 1)), z);\r\n                __m128i d2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x + 1)), z);\r\n                __m128i d3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow3 + x + 1)), z);\r\n\r\n                d2 = _mm_sub_epi16(d2, c2);\r\n                d3 = _mm_sub_epi16(d3, c3);\r\n\r\n                __m128i v0 = _mm_add_epi16(d0, _mm_add_epi16(d2, _mm_add_epi16(d1, d1)));\r\n                __m128i v1 = _mm_add_epi16(d1, _mm_add_epi16(d3, _mm_add_epi16(d2, d2)));\r\n                v0 = _mm_packus_epi16(_mm_add_epi16(v0, ftz), _mm_add_epi16(v1, ftz));\r\n                v0 = _mm_min_epu8(v0, ftz2);\r\n\r\n                _mm_storel_epi64((__m128i*)(dptr0 + x), v0);\r\n                _mm_storel_epi64((__m128i*)(dptr1 + x), _mm_unpackhi_epi64(v0, v0));\r\n            }\r\n        }\r\n    else //this else should be added to avoid going through the unoptimized loop\r\n    #endif\r\n    #if CV_NEON\r\n        int16x8_t ftz = vdupq_n_s16 ((short) ftzero);\r\n        uint8x8_t ftz2 = vdup_n_u8 (cv::saturate_cast<uchar>(ftzero*2));\r\n\r\n        for(; x <=size.width-9; x += 8 )\r\n        {\r\n            uint8x8_t c0 = vld1_u8 (srow0 + x - 1);\r\n            uint8x8_t c1 = vld1_u8 (srow1 + x - 1);\r\n            uint8x8_t d0 = vld1_u8 (srow0 + x + 1);\r\n            uint8x8_t d1 = vld1_u8 (srow1 + x + 1);\r\n\r\n            int16x8_t t0 = vreinterpretq_s16_u16 (vsubl_u8 (d0, c0));\r\n            int16x8_t t1 = vreinterpretq_s16_u16 (vsubl_u8 (d1, c1));\r\n\r\n            uint8x8_t c2 = vld1_u8 (srow2 + x - 1);\r\n            uint8x8_t c3 = vld1_u8 (srow3 + x - 1);\r\n            uint8x8_t d2 = vld1_u8 (srow2 + x + 1);\r\n            uint8x8_t d3 = vld1_u8 (srow3 + x + 1);\r\n\r\n            int16x8_t t2 = vreinterpretq_s16_u16 (vsubl_u8 (d2, c2));\r\n            int16x8_t t3 = vreinterpretq_s16_u16 (vsubl_u8 (d3, c3));\r\n\r\n            int16x8_t v0 = vaddq_s16 (vaddq_s16 (t2, t0), vaddq_s16 (t1, t1));\r\n            int16x8_t v1 = vaddq_s16 (vaddq_s16 (t3, t1), vaddq_s16 (t2, t2));\r\n\r\n\r\n            uint8x8_t v0_u8 = vqmovun_s16 (vaddq_s16 (v0, ftz));\r\n            uint8x8_t v1_u8 = vqmovun_s16 (vaddq_s16 (v1, ftz));\r\n            v0_u8 =  vmin_u8 (v0_u8, ftz2);\r\n            v1_u8 =  vmin_u8 (v1_u8, ftz2);\r\n            vqmovun_s16 (vaddq_s16 (v1, ftz));\r\n\r\n            vst1_u8 (dptr0 + x, v0_u8);\r\n            vst1_u8 (dptr1 + x, v1_u8);\r\n        }\r\n    \r\n#else  //this else should be added to avoid going through the unoptimized loop\r\n\r\n        for( ; x < size.width-1; x++ )\r\n        {\r\n            int d0 = srow0[x+1] - srow0[x-1], d1 = srow1[x+1] - srow1[x-1],\r\n                d2 = srow2[x+1] - srow2[x-1], d3 = srow3[x+1] - srow3[x-1];\r\n            int v0 = tab[d0 + d1*2 + d2 + OFS];\r\n            int v1 = tab[d1 + d2*2 + d3 + OFS];\r\n            dptr0[x] = (uchar)v0;\r\n            dptr1[x] = (uchar)v1;\r\n        }\r\n#endif"}}