You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

interp.cpp 14 kB

7 years ago
Fix warnings on Visual Studio (#1431) * Fix warnings C4244, C4267 in src/layer/yolov3detectionoutput.cpp C4244: '=': conversion from 'int' to 'float', possible loss of data C4244: 'initializing': conversion from 'float' to 'int', possible loss of data C4244: 'initializing': conversion from 'double' to 'float', possible loss of data C4244: 'return': conversion from 'double' to 'float', possible loss of data C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warnings C4244, C4267 in src/layer/yolodetectionoutput.cpp C4244: '=': conversion from 'int' to 'float', possible loss of data C4244: 'initializing': conversion from 'float' to 'int', possible loss of data C4244: 'initializing': conversion from 'double' to 'float', possible loss of data C4244: 'return': conversion from 'double' to 'float', possible loss of data C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4244 in src/layer/quantize.cpp C4244: 'initializing': conversion from 'double' to 'int', possible loss of data * Fix warnings C4244, C4267 in src/layer/detectionoutput.cpp C4244: '=': conversion from 'int' to 'float', possible loss of data C4244: 'initializing': conversion from 'double' to 'float', possible loss of data C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4244 in src/layer/roipooling.cpp C4244: 'initializing': conversion from 'double' to 'int', possible loss of data * Fix warning C4244 in src/layer/sigmoid.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4267 in src/layer/slice.cpp C4267: '=': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4267 in src/layer/softmax.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4244 in src/layer/interp.cpp C4244: '=': conversion from 'float' to 'int', possible loss of data C4244: 'initializing': conversion from 'double' to 'int', possible loss of data * Fix warning C4244 in src/layer/instancenorm.cpp C4244: 'initializing': conversion from 'double' to 'float', possible loss of data * Fix warning C4244 in src/layer/deconvolutiondepthwise.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4244 in src/layer/convolutiondepthwise.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4244 in src/net.cpp C4244: 'return': conversion from '__int64' to 'int', possible loss of data C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data C4267: 'return': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4244 in src/layer/bnll.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4267 in src/layer/concat.cpp C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4267 in tools/mxnet/mxnet2ncnn.cpp C4244: 'initializing': conversion from 'double' to 'float', possible loss of data C4267: '=': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data C4305: 'initializing': truncation from 'double' to 'float'
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
Fix warnings on Visual Studio (#1431) * Fix warnings C4244, C4267 in src/layer/yolov3detectionoutput.cpp C4244: '=': conversion from 'int' to 'float', possible loss of data C4244: 'initializing': conversion from 'float' to 'int', possible loss of data C4244: 'initializing': conversion from 'double' to 'float', possible loss of data C4244: 'return': conversion from 'double' to 'float', possible loss of data C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warnings C4244, C4267 in src/layer/yolodetectionoutput.cpp C4244: '=': conversion from 'int' to 'float', possible loss of data C4244: 'initializing': conversion from 'float' to 'int', possible loss of data C4244: 'initializing': conversion from 'double' to 'float', possible loss of data C4244: 'return': conversion from 'double' to 'float', possible loss of data C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4244 in src/layer/quantize.cpp C4244: 'initializing': conversion from 'double' to 'int', possible loss of data * Fix warnings C4244, C4267 in src/layer/detectionoutput.cpp C4244: '=': conversion from 'int' to 'float', possible loss of data C4244: 'initializing': conversion from 'double' to 'float', possible loss of data C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4244 in src/layer/roipooling.cpp C4244: 'initializing': conversion from 'double' to 'int', possible loss of data * Fix warning C4244 in src/layer/sigmoid.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4267 in src/layer/slice.cpp C4267: '=': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4267 in src/layer/softmax.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4244 in src/layer/interp.cpp C4244: '=': conversion from 'float' to 'int', possible loss of data C4244: 'initializing': conversion from 'double' to 'int', possible loss of data * Fix warning C4244 in src/layer/instancenorm.cpp C4244: 'initializing': conversion from 'double' to 'float', possible loss of data * Fix warning C4244 in src/layer/deconvolutiondepthwise.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4244 in src/layer/convolutiondepthwise.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4244 in src/net.cpp C4244: 'return': conversion from '__int64' to 'int', possible loss of data C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data C4267: 'return': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4244 in src/layer/bnll.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4267 in src/layer/concat.cpp C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4267 in tools/mxnet/mxnet2ncnn.cpp C4244: 'initializing': conversion from 'double' to 'float', possible loss of data C4267: '=': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data C4305: 'initializing': truncation from 'double' to 'float'
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
Fix warnings on Visual Studio (#1431) * Fix warnings C4244, C4267 in src/layer/yolov3detectionoutput.cpp C4244: '=': conversion from 'int' to 'float', possible loss of data C4244: 'initializing': conversion from 'float' to 'int', possible loss of data C4244: 'initializing': conversion from 'double' to 'float', possible loss of data C4244: 'return': conversion from 'double' to 'float', possible loss of data C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warnings C4244, C4267 in src/layer/yolodetectionoutput.cpp C4244: '=': conversion from 'int' to 'float', possible loss of data C4244: 'initializing': conversion from 'float' to 'int', possible loss of data C4244: 'initializing': conversion from 'double' to 'float', possible loss of data C4244: 'return': conversion from 'double' to 'float', possible loss of data C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4244 in src/layer/quantize.cpp C4244: 'initializing': conversion from 'double' to 'int', possible loss of data * Fix warnings C4244, C4267 in src/layer/detectionoutput.cpp C4244: '=': conversion from 'int' to 'float', possible loss of data C4244: 'initializing': conversion from 'double' to 'float', possible loss of data C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4244 in src/layer/roipooling.cpp C4244: 'initializing': conversion from 'double' to 'int', possible loss of data * Fix warning C4244 in src/layer/sigmoid.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4267 in src/layer/slice.cpp C4267: '=': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4267 in src/layer/softmax.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4244 in src/layer/interp.cpp C4244: '=': conversion from 'float' to 'int', possible loss of data C4244: 'initializing': conversion from 'double' to 'int', possible loss of data * Fix warning C4244 in src/layer/instancenorm.cpp C4244: 'initializing': conversion from 'double' to 'float', possible loss of data * Fix warning C4244 in src/layer/deconvolutiondepthwise.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4244 in src/layer/convolutiondepthwise.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4244 in src/net.cpp C4244: 'return': conversion from '__int64' to 'int', possible loss of data C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data C4267: 'return': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4244 in src/layer/bnll.cpp C4244: '=': conversion from 'double' to 'float', possible loss of data * Fix warning C4267 in src/layer/concat.cpp C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data * Fix warning C4267 in tools/mxnet/mxnet2ncnn.cpp C4244: 'initializing': conversion from 'double' to 'float', possible loss of data C4267: '=': conversion from 'size_t' to 'int', possible loss of data C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data C4305: 'initializing': truncation from 'double' to 'float'
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. // Tencent is pleased to support the open source community by making ncnn available.
  2. //
  3. // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
  4. //
  5. // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // https://opensource.org/licenses/BSD-3-Clause
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed
  11. // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. // specific language governing permissions and limitations under the License.
  14. #include "interp.h"
  15. #include <algorithm>
  16. namespace ncnn {
  17. DEFINE_LAYER_CREATOR(Interp);
  18. Interp::Interp()
  19. {
  20. one_blob_only = true;
  21. support_inplace = false;
  22. }
  23. int Interp::load_param(const ParamDict& pd)
  24. {
  25. resize_type = pd.get(0, 0);
  26. height_scale = pd.get(1, 1.f);
  27. width_scale = pd.get(2, 1.f);
  28. output_height = pd.get(3, 0);
  29. output_width = pd.get(4, 0);
  30. return 0;
  31. }
  32. static void linear_coeffs(int w, int outw, int* xofs, float* alpha)
  33. {
  34. double scale = (double)w / outw;
  35. for (int dx = 0; dx < outw; dx++)
  36. {
  37. float fx = (float)((dx + 0.5) * scale - 0.5);
  38. int sx = static_cast<int>(floor(fx));
  39. fx -= sx;
  40. if (sx < 0)
  41. {
  42. sx = 0;
  43. fx = 0.f;
  44. }
  45. if (sx >= w - 1)
  46. {
  47. sx = w - 2;
  48. fx = 1.f;
  49. }
  50. xofs[dx] = sx;
  51. alpha[dx*2 ] = 1.f - fx;
  52. alpha[dx*2 + 1] = fx;
  53. }
  54. }
  55. static void resize_bilinear_image(const Mat& src, Mat& dst, float* alpha, int* xofs, float* beta, int* yofs)
  56. {
  57. int w = dst.w;
  58. int h = dst.h;
  59. // loop body
  60. Mat rowsbuf0(w);
  61. Mat rowsbuf1(w);
  62. float* rows0 = rowsbuf0;
  63. float* rows1 = rowsbuf1;
  64. int prev_sy1 = -2;
  65. for (int dy = 0; dy < h; dy++ )
  66. {
  67. int sy = yofs[dy];
  68. if (sy == prev_sy1)
  69. {
  70. // reuse all rows
  71. }
  72. else if (sy == prev_sy1 + 1)
  73. {
  74. // hresize one row
  75. float* rows0_old = rows0;
  76. rows0 = rows1;
  77. rows1 = rows0_old;
  78. const float* S1 = src.row(sy+1);
  79. const float* alphap = alpha;
  80. float* rows1p = rows1;
  81. for (int dx = 0; dx < w; dx++)
  82. {
  83. int sx = xofs[dx];
  84. const float* S1p = S1 + sx;
  85. float a0 = alphap[0];
  86. float a1 = alphap[1];
  87. rows1p[dx] = S1p[0]*a0 + S1p[1]*a1;
  88. alphap += 2;
  89. }
  90. }
  91. else
  92. {
  93. // hresize two rows
  94. const float* S0 = src.row(sy);
  95. const float* S1 = src.row(sy+1);
  96. const float* alphap = alpha;
  97. float* rows0p = rows0;
  98. float* rows1p = rows1;
  99. for (int dx = 0; dx < w; dx++)
  100. {
  101. int sx = xofs[dx];
  102. const float* S0p = S0 + sx;
  103. const float* S1p = S1 + sx;
  104. float a0 = alphap[0];
  105. float a1 = alphap[1];
  106. rows0p[dx] = S0p[0]*a0 + S0p[1]*a1;
  107. rows1p[dx] = S1p[0]*a0 + S1p[1]*a1;
  108. alphap += 2;
  109. }
  110. }
  111. prev_sy1 = sy;
  112. // vresize
  113. float b0 = beta[0];
  114. float b1 = beta[1];
  115. float* rows0p = rows0;
  116. float* rows1p = rows1;
  117. float* Dp = dst.row(dy);
  118. for (int dx = 0; dx < w; dx++)
  119. {
  120. // D[x] = rows0[x]*b0 + rows1[x]*b1;
  121. *Dp++ = *rows0p++ * b0 + *rows1p++ * b1;
  122. }
  123. beta += 2;
  124. }
  125. }
  126. static inline void interpolate_cubic(float fx, float* coeffs)
  127. {
  128. const float A = -0.75f;
  129. float fx0 = fx + 1;
  130. float fx1 = fx;
  131. float fx2 = 1 - fx;
  132. // float fx3 = 2 - fx;
  133. coeffs[0] = A * fx0*fx0*fx0 - 5*A * fx0*fx0 + 8*A * fx0 - 4*A;
  134. coeffs[1] = (A+2) * fx1*fx1*fx1 - (A+3) * fx1*fx1 + 1;
  135. coeffs[2] = (A+2) * fx2*fx2*fx2 - (A+3) * fx2*fx2 + 1;
  136. coeffs[3] = 1.f - coeffs[0] - coeffs[1] - coeffs[2];
  137. }
  138. static void cubic_coeffs(int w, int outw, int* xofs, float* alpha)
  139. {
  140. double scale = (double)w / outw;
  141. for (int dx = 0; dx < outw; dx++)
  142. {
  143. float fx = (float)((dx + 0.5) * scale - 0.5);
  144. int sx = static_cast<int>(floor(fx));
  145. fx -= sx;
  146. interpolate_cubic(fx, alpha + dx*4);
  147. if (sx <= -1)
  148. {
  149. sx = 1;
  150. alpha[dx*4 +0] = 1.f - alpha[dx*4 +3];
  151. alpha[dx*4 +1] = alpha[dx*4 +3];
  152. alpha[dx*4 +2] = 0.f;
  153. alpha[dx*4 +3] = 0.f;
  154. }
  155. if (sx == 0)
  156. {
  157. sx = 1;
  158. alpha[dx*4 +0] = alpha[dx*4 +0] + alpha[dx*4 +1];
  159. alpha[dx*4 +1] = alpha[dx*4 +2];
  160. alpha[dx*4 +2] = alpha[dx*4 +3];
  161. alpha[dx*4 +3] = 0.f;
  162. }
  163. if (sx == w - 2)
  164. {
  165. sx = w - 3;
  166. alpha[dx*4 +3] = alpha[dx*4 +2] + alpha[dx*4 +3];
  167. alpha[dx*4 +2] = alpha[dx*4 +1];
  168. alpha[dx*4 +1] = alpha[dx*4 +0];
  169. alpha[dx*4 +0] = 0.f;
  170. }
  171. if (sx >= w - 1)
  172. {
  173. sx = w - 3;
  174. alpha[dx*4 +3] = 1.f - alpha[dx*4 +0];
  175. alpha[dx*4 +2] = alpha[dx*4 +0];
  176. alpha[dx*4 +1] = 0.f;
  177. alpha[dx*4 +0] = 0.f;
  178. }
  179. xofs[dx] = sx;
  180. }
  181. }
  182. static void resize_bicubic_image(const Mat& src, Mat& dst, float* alpha, int* xofs, float* beta, int* yofs)
  183. {
  184. int w = dst.w;
  185. int h = dst.h;
  186. // loop body
  187. Mat rowsbuf0(w);
  188. Mat rowsbuf1(w);
  189. Mat rowsbuf2(w);
  190. Mat rowsbuf3(w);
  191. float* rows0 = rowsbuf0;
  192. float* rows1 = rowsbuf1;
  193. float* rows2 = rowsbuf2;
  194. float* rows3 = rowsbuf3;
  195. int prev_sy1 = -3;
  196. for (int dy = 0; dy < h; dy++ )
  197. {
  198. int sy = yofs[dy];
  199. if (sy == prev_sy1)
  200. {
  201. // reuse all rows
  202. }
  203. else if (sy == prev_sy1 + 1)
  204. {
  205. // hresize one row
  206. float* rows0_old = rows0;
  207. rows0 = rows1;
  208. rows1 = rows2;
  209. rows2 = rows3;
  210. rows3 = rows0_old;
  211. const float* S3 = src.row(sy+2);
  212. const float* alphap = alpha;
  213. float* rows3p = rows3;
  214. for (int dx = 0; dx < w; dx++)
  215. {
  216. int sx = xofs[dx];
  217. const float* S3p = S3 + sx;
  218. float a0 = alphap[0];
  219. float a1 = alphap[1];
  220. float a2 = alphap[2];
  221. float a3 = alphap[3];
  222. rows3p[dx] = S3p[-1]*a0 + S3p[0]*a1 + S3p[1]*a2 + S3p[2]*a3;
  223. alphap += 4;
  224. }
  225. }
  226. else if (sy == prev_sy1 + 2)
  227. {
  228. // hresize two rows
  229. float* rows0_old = rows0;
  230. float* rows1_old = rows1;
  231. rows0 = rows2;
  232. rows1 = rows3;
  233. rows2 = rows0_old;
  234. rows3 = rows1_old;
  235. const float* S2 = src.row(sy+1);
  236. const float* S3 = src.row(sy+2);
  237. const float* alphap = alpha;
  238. float* rows2p = rows2;
  239. float* rows3p = rows3;
  240. for (int dx = 0; dx < w; dx++)
  241. {
  242. int sx = xofs[dx];
  243. const float* S2p = S2 + sx;
  244. const float* S3p = S3 + sx;
  245. float a0 = alphap[0];
  246. float a1 = alphap[1];
  247. float a2 = alphap[2];
  248. float a3 = alphap[3];
  249. rows2p[dx] = S2p[-1]*a0 + S2p[0]*a1 + S2p[1]*a2 + S2p[2]*a3;
  250. rows3p[dx] = S3p[-1]*a0 + S3p[0]*a1 + S3p[1]*a2 + S3p[2]*a3;
  251. alphap += 4;
  252. }
  253. }
  254. else if (sy == prev_sy1 + 3)
  255. {
  256. // hresize three rows
  257. float* rows0_old = rows0;
  258. float* rows1_old = rows1;
  259. float* rows2_old = rows2;
  260. rows0 = rows3;
  261. rows1 = rows0_old;
  262. rows2 = rows1_old;
  263. rows3 = rows2_old;
  264. const float* S1 = src.row(sy);
  265. const float* S2 = src.row(sy+1);
  266. const float* S3 = src.row(sy+2);
  267. const float* alphap = alpha;
  268. float* rows1p = rows1;
  269. float* rows2p = rows2;
  270. float* rows3p = rows3;
  271. for (int dx = 0; dx < w; dx++)
  272. {
  273. int sx = xofs[dx];
  274. const float* S1p = S1 + sx;
  275. const float* S2p = S2 + sx;
  276. const float* S3p = S3 + sx;
  277. float a0 = alphap[0];
  278. float a1 = alphap[1];
  279. float a2 = alphap[2];
  280. float a3 = alphap[3];
  281. rows1p[dx] = S1p[-1]*a0 + S1p[0]*a1 + S1p[1]*a2 + S1p[2]*a3;
  282. rows2p[dx] = S2p[-1]*a0 + S2p[0]*a1 + S2p[1]*a2 + S2p[2]*a3;
  283. rows3p[dx] = S3p[-1]*a0 + S3p[0]*a1 + S3p[1]*a2 + S3p[2]*a3;
  284. alphap += 4;
  285. }
  286. }
  287. else
  288. {
  289. // hresize four rows
  290. const float* S0 = src.row(sy-1);
  291. const float* S1 = src.row(sy);
  292. const float* S2 = src.row(sy+1);
  293. const float* S3 = src.row(sy+2);
  294. const float* alphap = alpha;
  295. float* rows0p = rows0;
  296. float* rows1p = rows1;
  297. float* rows2p = rows2;
  298. float* rows3p = rows3;
  299. for (int dx = 0; dx < w; dx++)
  300. {
  301. int sx = xofs[dx];
  302. const float* S0p = S0 + sx;
  303. const float* S1p = S1 + sx;
  304. const float* S2p = S2 + sx;
  305. const float* S3p = S3 + sx;
  306. float a0 = alphap[0];
  307. float a1 = alphap[1];
  308. float a2 = alphap[2];
  309. float a3 = alphap[3];
  310. rows0p[dx] = S0p[-1]*a0 + S0p[0]*a1 + S0p[1]*a2 + S0p[2]*a3;
  311. rows1p[dx] = S1p[-1]*a0 + S1p[0]*a1 + S1p[1]*a2 + S1p[2]*a3;
  312. rows2p[dx] = S2p[-1]*a0 + S2p[0]*a1 + S2p[1]*a2 + S2p[2]*a3;
  313. rows3p[dx] = S3p[-1]*a0 + S3p[0]*a1 + S3p[1]*a2 + S3p[2]*a3;
  314. alphap += 4;
  315. }
  316. }
  317. prev_sy1 = sy;
  318. // vresize
  319. float b0 = beta[0];
  320. float b1 = beta[1];
  321. float b2 = beta[2];
  322. float b3 = beta[3];
  323. float* rows0p = rows0;
  324. float* rows1p = rows1;
  325. float* rows2p = rows2;
  326. float* rows3p = rows3;
  327. float* Dp = dst.row(dy);
  328. for (int dx = 0; dx < w; dx++)
  329. {
  330. // D[x] = rows0[x]*b0 + rows1[x]*b1 + rows2[x]*b2 + rows3[x]*b3;
  331. *Dp++ = *rows0p++ * b0 + *rows1p++ * b1 + *rows2p++ * b2 + *rows3p++ * b3;
  332. }
  333. beta += 4;
  334. }
  335. }
  336. int Interp::forward(const Mat &bottom_blob, Mat &top_blob, const Option& opt) const
  337. {
  338. int h = bottom_blob.h;
  339. int w = bottom_blob.w;
  340. int c = bottom_blob.c;
  341. size_t elemsize = bottom_blob.elemsize;
  342. int oh = output_height;
  343. int ow = output_width;
  344. if (bottom_blob.dims == 1)
  345. {
  346. h = 1;
  347. w = 1;
  348. c = bottom_blob.w;
  349. }
  350. if (oh == 0 || ow == 0)
  351. {
  352. oh = static_cast<int>(h * height_scale);
  353. ow = static_cast<int>(w * width_scale);
  354. }
  355. if (oh == h && ow == w)
  356. {
  357. top_blob = bottom_blob;
  358. return 0;
  359. }
  360. top_blob.create(ow, oh, c, elemsize, opt.blob_allocator);
  361. if (top_blob.empty())
  362. return -100;
  363. if (bottom_blob.dims == 1)
  364. {
  365. #pragma omp parallel for num_threads(opt.num_threads)
  366. for (int q = 0; q < c; ++q)
  367. {
  368. Mat top_blob_c = top_blob.channel(q);
  369. const float *ptr = ((const float*)bottom_blob.data + q);
  370. top_blob_c.fill(*ptr);
  371. }
  372. return 0;
  373. }
  374. if (resize_type == 1)// nearest
  375. {
  376. const float hs = output_height ? h / (float)output_height : 1.f / height_scale;
  377. const float ws = output_width ? w / (float)output_width : 1.f / width_scale;
  378. #pragma omp parallel for num_threads(opt.num_threads)
  379. for (int q = 0; q < c; q++)
  380. {
  381. const float* ptr = bottom_blob.channel(q);
  382. float* outptr = top_blob.channel(q);
  383. for (int y = 0; y < oh; y++)
  384. {
  385. int in_y = std::min((int) (y * hs), (h - 1));
  386. for (int x = 0; x < ow; x++)
  387. {
  388. int in_x = std::min((int) (x * ws), (w - 1));
  389. *outptr++ = ptr[in_y * w + in_x];
  390. }
  391. }
  392. }
  393. return 0;
  394. }
  395. else if (resize_type == 2)// bilinear
  396. {
  397. int* buf = new int[ow + oh + ow*2 + oh*2];
  398. int* xofs = buf;//new int[ow];
  399. int* yofs = buf + ow;//new int[oh];
  400. float* alpha = (float*)(buf + ow + oh);//new float[ow * 2];
  401. float* beta = (float*)(buf + ow + oh + ow*2);//new float[oh * 2];
  402. linear_coeffs(w, ow, xofs, alpha);
  403. linear_coeffs(h, oh, yofs, beta);
  404. #pragma omp parallel for num_threads(opt.num_threads)
  405. for (int q = 0; q < c; ++q)
  406. {
  407. const Mat src = bottom_blob.channel(q);
  408. Mat dst = top_blob.channel(q);
  409. resize_bilinear_image(src, dst, alpha, xofs, beta, yofs);
  410. }
  411. delete[] buf;
  412. return 0;
  413. }
  414. else if (resize_type == 3)// bicubic
  415. {
  416. int* buf = new int[ow + oh + ow*4 + oh*4];
  417. int* xofs = buf;//new int[ow];
  418. int* yofs = buf + ow;//new int[oh];
  419. float* alpha = (float*)(buf + ow + oh);//new float[ow * 4];
  420. float* beta = (float*)(buf + ow + oh + ow*4);//new float[oh * 4];
  421. cubic_coeffs(w, ow, xofs, alpha);
  422. cubic_coeffs(h, oh, yofs, beta);
  423. #pragma omp parallel for num_threads(opt.num_threads)
  424. for (int q = 0; q < c; ++q)
  425. {
  426. const Mat src = bottom_blob.channel(q);
  427. Mat dst = top_blob.channel(q);
  428. resize_bicubic_image(src, dst, alpha, xofs, beta, yofs);
  429. }
  430. delete[] buf;
  431. return 0;
  432. }
  433. else
  434. {
  435. fprintf(stderr, "unsupported resize type %d %d %d\n", resize_type, oh, ow);
  436. return -233;
  437. }
  438. }
  439. } // namespace ncnn