| 1759 | } |
| 1760 | |
| 1761 | void cv::transform( InputArray _src, OutputArray _dst, InputArray _mtx ) |
| 1762 | { |
| 1763 | Mat src = _src.getMat(), m = _mtx.getMat(); |
| 1764 | int depth = src.depth(), scn = src.channels(), dcn = m.rows; |
| 1765 | CV_Assert( scn == m.cols || scn + 1 == m.cols ); |
| 1766 | bool isDiag = false; |
| 1767 | |
| 1768 | _dst.create( src.size(), CV_MAKETYPE(depth, dcn) ); |
| 1769 | Mat dst = _dst.getMat(); |
| 1770 | |
| 1771 | int mtype = depth == CV_32S || depth == CV_64F ? CV_64F : CV_32F; |
| 1772 | AutoBuffer<double> _mbuf; |
| 1773 | double* mbuf; |
| 1774 | |
| 1775 | if( !m.isContinuous() || m.type() != mtype || m.cols != scn + 1 ) |
| 1776 | { |
| 1777 | _mbuf.allocate(dcn*(scn+1)); |
| 1778 | mbuf = (double*)_mbuf; |
| 1779 | Mat tmp(dcn, scn+1, mtype, mbuf); |
| 1780 | memset(tmp.data, 0, tmp.total()*tmp.elemSize()); |
| 1781 | if( m.cols == scn+1 ) |
| 1782 | m.convertTo(tmp, mtype); |
| 1783 | else |
| 1784 | { |
| 1785 | Mat tmppart = tmp.colRange(0, m.cols); |
| 1786 | m.convertTo(tmppart, mtype); |
| 1787 | } |
| 1788 | m = tmp; |
| 1789 | } |
| 1790 | else |
| 1791 | mbuf = (double*)m.data; |
| 1792 | |
| 1793 | if( scn == dcn ) |
| 1794 | { |
| 1795 | int i, j; |
| 1796 | double eps = mtype == CV_32F ? FLT_EPSILON : DBL_EPSILON; |
| 1797 | |
| 1798 | if( scn == 1 ) |
| 1799 | { |
| 1800 | double alpha, beta; |
| 1801 | if( mtype == CV_32F ) |
| 1802 | alpha = m.at<float>(0), beta = m.at<float>(1); |
| 1803 | else |
| 1804 | alpha = m.at<double>(0), beta = m.at<double>(1); |
| 1805 | src.convertTo(dst, dst.type(), alpha, beta); |
| 1806 | return; |
| 1807 | } |
| 1808 | |
| 1809 | for( i = 0, isDiag = true; isDiag && i < scn; i++ ) |
| 1810 | { |
| 1811 | for( j = 0; isDiag && j < scn; j++ ) |
| 1812 | { |
| 1813 | double v = mtype == CV_32F ? m.at<float>(i, j) : m.at<double>(i, j); |
| 1814 | if( i != j && fabs(v) > eps ) |
| 1815 | isDiag = false; |
| 1816 | } |
| 1817 | } |
| 1818 | } |
nothing calls this directly
no test coverage detected