{"action":"opened","issue":{"url":"https://api.github.com/repos/Itseez/opencv/issues/5775","labels_url":"https://api.github.com/repos/Itseez/opencv/issues/5775/labels{/name}","comments_url":"https://api.github.com/repos/Itseez/opencv/issues/5775/comments","events_url":"https://api.github.com/repos/Itseez/opencv/issues/5775/events","html_url":"https://github.com/Itseez/opencv/issues/5775","id":121229203,"number":5775,"title":"arithm_op: wrong data length for actualScalarDepth()","user":{"login":"rvogt","id":16223681,"avatar_url":"https://avatars.githubusercontent.com/u/16223681?v=3","gravatar_id":"","url":"https://api.github.com/users/rvogt","html_url":"https://github.com/rvogt","followers_url":"https://api.github.com/users/rvogt/followers","following_url":"https://api.github.com/users/rvogt/following{/other_user}","gists_url":"https://api.github.com/users/rvogt/gists{/gist_id}","starred_url":"https://api.github.com/users/rvogt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rvogt/subscriptions","organizations_url":"https://api.github.com/users/rvogt/orgs","repos_url":"https://api.github.com/users/rvogt/repos","events_url":"https://api.github.com/users/rvogt/events{/privacy}","received_events_url":"https://api.github.com/users/rvogt/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-12-09T12:45:13Z","updated_at":"2015-12-09T12:45:13Z","closed_at":null,"body":"Hi,\r\n\r\ni sometimes got an exception when calling subtract(255, srcImage, destImage), where srcImage is of type CV_8UC3.\r\nI think i found the bug at a quite central position, so it would be great if someone responsible could verify and fix it:\r\n\r\n*core/arithm.cpp* in function *arithm_op*\r\n```cpp\r\n...\r\nif( dims1 != dims2 || sz1 != sz2 || cn != cn2 ||\r\n        (kind1 == _InputArray::MATX && (sz1 == Size(1,4) || sz1 == Size(1,1))) ||\r\n        (kind2 == _InputArray::MATX && (sz2 == Size(1,4) || sz2 == Size(1,1))) )\r\n{\r\n    if( checkScalar(*psrc1, type2, kind1, kind2) )\r\n    {\r\n        // src1 is a scalar; swap it with src2\r\n        swap(psrc1, psrc2);\r\n        swap(sz1, sz2);\r\n        swap(type1, type2);\r\n        swap(depth1, depth2);\r\n        swap(cn, cn2);\r\n        swap(dims1, dims2);\r\n        swapped12 = true;\r\n        if( oclop == OCL_OP_SUB )\r\n            oclop = OCL_OP_RSUB;\r\n        if ( oclop == OCL_OP_DIV_SCALE )\r\n            oclop = OCL_OP_RDIV_SCALE;\r\n    }\r\n    else if( !checkScalar(*psrc2, type1, kind2, kind1) )\r\n        CV_Error( CV_StsUnmatchedSizes,\r\n                 \"The operation is neither 'array op array' \"\r\n                 \"(where arrays have the same size and the same number of channels), \"\r\n                 \"nor 'array op scalar', nor 'scalar op array'\" );\r\n    haveScalar = true;\r\n    CV_Assert(type2 == CV_64F && (sz2.height == 1 || sz2.height == 4));\r\n\r\n    if (!muldiv)\r\n    {\r\n        Mat sc = psrc2->getMat();\r\n        depth2 = actualScalarDepth(sc.ptr<double>(), cn);    // <== cn should be cn2\r\n        if( depth2 == CV_64F && (depth1 < CV_32S || depth1 == CV_32F) )\r\n            depth2 = CV_32F;\r\n    }\r\n    else\r\n        depth2 = CV_64F;\r\n}\r\n...\r\n```\r\nI think, the line \r\n```cpp\r\ndepth2 = actualScalarDepth(sc.ptr<double>(), cn);\r\n```\r\nshould be changed to\r\n```cpp\r\ndepth2 = actualScalarDepth(sc.ptr<double>(), cn2);\r\n```\r\nIn my case, initially cn = 1 and cn2 = 3, then after swapping cn = 3.\r\nThis leads to an invalid memory access behind my scalar in the actualScalarDepth function:\r\n```cpp\r\nstatic int actualScalarDepth(const double* data, int len)\r\n{\r\n    int i = 0, minval = INT_MAX, maxval = INT_MIN;\r\n    for(; i < len; ++i)\r\n    {\r\n        int ival = cvRound(data[i]);\r\n        if( ival != data[i] )\r\n            break;\r\n        minval = MIN(minval, ival);\r\n        maxval = MAX(maxval, ival);\r\n    }\r\n    return i < len ? CV_64F :\r\n        minval >= 0 && maxval <= (int)UCHAR_MAX ? CV_8U :\r\n        minval >= (int)SCHAR_MIN && maxval <= (int)SCHAR_MAX ? CV_8S :\r\n        minval >= 0 && maxval <= (int)USHRT_MAX ? CV_16U :\r\n        minval >= (int)SHRT_MIN && maxval <= (int)SHRT_MAX ? CV_16S :\r\n        CV_32S;\r\n}\r\n```\r\nIf there is a NAN at data[1] or data[2], cvRound() throws an exception\r\n"}}