| 72 | |
| 73 | template<typename T, int order> |
| 74 | void transform(Param<T> output, CParam<T> input, CParam<float> transform, |
| 75 | const bool inverse, const bool perspective, |
| 76 | af_interp_type method) { |
| 77 | typedef typename af::dtype_traits<T>::base_type BT; |
| 78 | typedef wtype_t<BT> WT; |
| 79 | |
| 80 | const af::dim4 idims = input.dims(); |
| 81 | const af::dim4 odims = output.dims(); |
| 82 | const af::dim4 tdims = transform.dims(); |
| 83 | const af::dim4 tstrides = transform.strides(); |
| 84 | const af::dim4 istrides = input.strides(); |
| 85 | const af::dim4 ostrides = output.strides(); |
| 86 | |
| 87 | T *out = output.get(); |
| 88 | const float *tf = transform.get(); |
| 89 | |
| 90 | int batch_size = 1; |
| 91 | if (idims[2] != tdims[2]) batch_size = idims[2]; |
| 92 | |
| 93 | Interp2<T, WT, order> interp; |
| 94 | for (int idw = 0; idw < (int)odims[3]; idw++) { |
| 95 | dim_t out_offw = idw * ostrides[3]; |
| 96 | dim_t in_offw = (idims[3] > 1) * idw * istrides[3]; |
| 97 | dim_t tf_offw = (tdims[3] > 1) * idw * tstrides[3]; |
| 98 | |
| 99 | for (int idz = 0; idz < (int)odims[2]; idz += batch_size) { |
| 100 | dim_t out_offzw = out_offw + idz * ostrides[2]; |
| 101 | dim_t in_offzw = in_offw + (idims[2] > 1) * idz * istrides[2]; |
| 102 | dim_t tf_offzw = tf_offw + (tdims[2] > 1) * idz * tstrides[2]; |
| 103 | |
| 104 | const float *tptr = tf + tf_offzw; |
| 105 | |
| 106 | float tmat[9]; |
| 107 | calc_transform_inverse(tmat, tptr, inverse, perspective, |
| 108 | perspective ? 9 : 6); |
| 109 | |
| 110 | for (int idy = 0; idy < (int)odims[1]; idy++) { |
| 111 | for (int idx = 0; idx < (int)odims[0]; idx++) { |
| 112 | WT xidi = idx * tmat[0] + idy * tmat[1] + tmat[2]; |
| 113 | WT yidi = idx * tmat[3] + idy * tmat[4] + tmat[5]; |
| 114 | |
| 115 | if (perspective) { |
| 116 | WT W = idx * tmat[6] + idy * tmat[7] + tmat[8]; |
| 117 | xidi /= W; |
| 118 | yidi /= W; |
| 119 | } |
| 120 | |
| 121 | // FIXME: Nearest and lower do not do clamping, but other |
| 122 | // methods do Make it consistent |
| 123 | bool clamp = order != 1; |
| 124 | bool condX = xidi >= -0.0001 && xidi < idims[0]; |
| 125 | bool condY = yidi >= -0.0001 && yidi < idims[1]; |
| 126 | |
| 127 | int ooff = out_offzw + idy * ostrides[1] + idx; |
| 128 | if (condX && condY) { |
| 129 | interp(output, ooff, input, in_offzw, xidi, yidi, |
| 130 | method, batch_size, clamp); |
| 131 | } else { |
no test coverage detected