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

679 lines
18KB

  1. /*
  2. * Discrete wavelet transform
  3. * Copyright (c) 2007 Kamil Nowosad
  4. * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu@gmail.com>
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with FFmpeg; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. /**
  23. * @file
  24. * Discrete wavelet transform
  25. */
  26. #include "libavutil/avassert.h"
  27. #include "libavutil/common.h"
  28. #include "libavutil/mem.h"
  29. #include "jpeg2000dwt.h"
  30. #include "internal.h"
  31. /* Defines for 9/7 DWT lifting parameters.
  32. * Parameters are in float. */
  33. #define F_LFTG_ALPHA 1.586134342059924f
  34. #define F_LFTG_BETA 0.052980118572961f
  35. #define F_LFTG_GAMMA 0.882911075530934f
  36. #define F_LFTG_DELTA 0.443506852043971f
  37. #define F_LFTG_K 1.230174104914001f
  38. #define F_LFTG_X 1.625732422f
  39. /* FIXME: Why use 1.625732422 instead of 1/F_LFTG_K?
  40. * Incorrect value in JPEG2000 norm.
  41. * see (ISO/IEC 15444:1 (version 2002) F.3.8.2 */
  42. /* Lifting parameters in integer format.
  43. * Computed as param = (float param) * (1 << 16) */
  44. #define I_LFTG_ALPHA 103949
  45. #define I_LFTG_BETA 3472
  46. #define I_LFTG_GAMMA 57862
  47. #define I_LFTG_DELTA 29066
  48. #define I_LFTG_K 80621
  49. #define I_LFTG_X 106544
  50. static inline void extend53(int *p, int i0, int i1)
  51. {
  52. p[i0 - 1] = p[i0 + 1];
  53. p[i1] = p[i1 - 2];
  54. p[i0 - 2] = p[i0 + 2];
  55. p[i1 + 1] = p[i1 - 3];
  56. }
  57. static inline void extend97_float(float *p, int i0, int i1)
  58. {
  59. int i;
  60. for (i = 1; i <= 4; i++) {
  61. p[i0 - i] = p[i0 + i];
  62. p[i1 + i - 1] = p[i1 - i - 1];
  63. }
  64. }
  65. static inline void extend97_int(int32_t *p, int i0, int i1)
  66. {
  67. int i;
  68. for (i = 1; i <= 4; i++) {
  69. p[i0 - i] = p[i0 + i];
  70. p[i1 + i - 1] = p[i1 - i - 1];
  71. }
  72. }
  73. static void sd_1d53(int *p, int i0, int i1)
  74. {
  75. int i;
  76. if (i1 <= i0 + 1) {
  77. if (i0 == 1)
  78. p[1] <<= 1;
  79. return;
  80. }
  81. extend53(p, i0, i1);
  82. for (i = (i0+1)/2 - 1; i < (i1+1)/2; i++)
  83. p[2*i+1] -= (p[2*i] + p[2*i+2]) >> 1;
  84. for (i = (i0+1)/2; i < (i1+1)/2; i++)
  85. p[2*i] += (p[2*i-1] + p[2*i+1] + 2) >> 2;
  86. }
  87. static void dwt_encode53(DWTContext *s, int *t)
  88. {
  89. int lev,
  90. w = s->linelen[s->ndeclevels-1][0];
  91. int *line = s->i_linebuf;
  92. line += 3;
  93. for (lev = s->ndeclevels-1; lev >= 0; lev--){
  94. int lh = s->linelen[lev][0],
  95. lv = s->linelen[lev][1],
  96. mh = s->mod[lev][0],
  97. mv = s->mod[lev][1],
  98. lp;
  99. int *l;
  100. // VER_SD
  101. l = line + mv;
  102. for (lp = 0; lp < lh; lp++) {
  103. int i, j = 0;
  104. for (i = 0; i < lv; i++)
  105. l[i] = t[w*i + lp];
  106. sd_1d53(line, mv, mv + lv);
  107. // copy back and deinterleave
  108. for (i = mv; i < lv; i+=2, j++)
  109. t[w*j + lp] = l[i];
  110. for (i = 1-mv; i < lv; i+=2, j++)
  111. t[w*j + lp] = l[i];
  112. }
  113. // HOR_SD
  114. l = line + mh;
  115. for (lp = 0; lp < lv; lp++){
  116. int i, j = 0;
  117. for (i = 0; i < lh; i++)
  118. l[i] = t[w*lp + i];
  119. sd_1d53(line, mh, mh + lh);
  120. // copy back and deinterleave
  121. for (i = mh; i < lh; i+=2, j++)
  122. t[w*lp + j] = l[i];
  123. for (i = 1-mh; i < lh; i+=2, j++)
  124. t[w*lp + j] = l[i];
  125. }
  126. }
  127. }
  128. static void sd_1d97_float(float *p, int i0, int i1)
  129. {
  130. int i;
  131. if (i1 <= i0 + 1) {
  132. if (i0 == 1)
  133. p[1] *= F_LFTG_X;
  134. else
  135. p[0] *= F_LFTG_K;
  136. return;
  137. }
  138. extend97_float(p, i0, i1);
  139. i0++; i1++;
  140. for (i = i0/2 - 2; i < i1/2 + 1; i++)
  141. p[2*i+1] -= 1.586134 * (p[2*i] + p[2*i+2]);
  142. for (i = i0/2 - 1; i < i1/2 + 1; i++)
  143. p[2*i] -= 0.052980 * (p[2*i-1] + p[2*i+1]);
  144. for (i = i0/2 - 1; i < i1/2; i++)
  145. p[2*i+1] += 0.882911 * (p[2*i] + p[2*i+2]);
  146. for (i = i0/2; i < i1/2; i++)
  147. p[2*i] += 0.443506 * (p[2*i-1] + p[2*i+1]);
  148. }
  149. static void dwt_encode97_float(DWTContext *s, float *t)
  150. {
  151. int lev,
  152. w = s->linelen[s->ndeclevels-1][0];
  153. float *line = s->f_linebuf;
  154. line += 5;
  155. for (lev = s->ndeclevels-1; lev >= 0; lev--){
  156. int lh = s->linelen[lev][0],
  157. lv = s->linelen[lev][1],
  158. mh = s->mod[lev][0],
  159. mv = s->mod[lev][1],
  160. lp;
  161. float *l;
  162. av_assert1(!mh && !mv);
  163. // HOR_SD
  164. l = line + mh;
  165. for (lp = 0; lp < lv; lp++){
  166. int i, j = 0;
  167. for (i = 0; i < lh; i++)
  168. l[i] = t[w*lp + i];
  169. sd_1d97_float(line, mh, mh + lh);
  170. // copy back and deinterleave
  171. for (i = mh; i < lh; i+=2, j++)
  172. t[w*lp + j] = F_LFTG_X * l[i] / 2;
  173. for (i = 1-mh; i < lh; i+=2, j++)
  174. t[w*lp + j] = F_LFTG_K * l[i] / 2;
  175. }
  176. // VER_SD
  177. l = line + mv;
  178. for (lp = 0; lp < lh; lp++) {
  179. int i, j = 0;
  180. for (i = 0; i < lv; i++)
  181. l[i] = t[w*i + lp];
  182. sd_1d97_float(line, mv, mv + lv);
  183. // copy back and deinterleave
  184. for (i = mv; i < lv; i+=2, j++)
  185. t[w*j + lp] = F_LFTG_X * l[i] / 2;
  186. for (i = 1-mv; i < lv; i+=2, j++)
  187. t[w*j + lp] = F_LFTG_K * l[i] / 2;
  188. }
  189. }
  190. }
  191. static void sd_1d97_int(int *p, int i0, int i1)
  192. {
  193. int i;
  194. if (i1 <= i0 + 1) {
  195. if (i0 == 1)
  196. p[1] = (p[1] * I_LFTG_X + (1<<15)) >> 16;
  197. else
  198. p[0] = (p[0] * I_LFTG_K + (1<<15)) >> 16;
  199. return;
  200. }
  201. extend97_int(p, i0, i1);
  202. i0++; i1++;
  203. for (i = i0/2 - 2; i < i1/2 + 1; i++)
  204. p[2 * i + 1] -= (I_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16;
  205. for (i = i0/2 - 1; i < i1/2 + 1; i++)
  206. p[2 * i] -= (I_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
  207. for (i = i0/2 - 1; i < i1/2; i++)
  208. p[2 * i + 1] += (I_LFTG_GAMMA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16;
  209. for (i = i0/2; i < i1/2; i++)
  210. p[2 * i] += (I_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
  211. }
  212. static void dwt_encode97_int(DWTContext *s, int *t)
  213. {
  214. int lev,
  215. w = s->linelen[s->ndeclevels-1][0];
  216. int *line = s->i_linebuf;
  217. line += 5;
  218. for (lev = s->ndeclevels-1; lev >= 0; lev--){
  219. int lh = s->linelen[lev][0],
  220. lv = s->linelen[lev][1],
  221. mh = s->mod[lev][0],
  222. mv = s->mod[lev][1],
  223. lp;
  224. int *l;
  225. // VER_SD
  226. l = line + mv;
  227. for (lp = 0; lp < lh; lp++) {
  228. int i, j = 0;
  229. for (i = 0; i < lv; i++)
  230. l[i] = t[w*i + lp];
  231. sd_1d97_int(line, mv, mv + lv);
  232. // copy back and deinterleave
  233. for (i = mv; i < lv; i+=2, j++)
  234. t[w*j + lp] = ((l[i] * I_LFTG_X) + (1 << 16)) >> 17;
  235. for (i = 1-mv; i < lv; i+=2, j++)
  236. t[w*j + lp] = ((l[i] * I_LFTG_K) + (1 << 16)) >> 17;
  237. }
  238. // HOR_SD
  239. l = line + mh;
  240. for (lp = 0; lp < lv; lp++){
  241. int i, j = 0;
  242. for (i = 0; i < lh; i++)
  243. l[i] = t[w*lp + i];
  244. sd_1d97_int(line, mh, mh + lh);
  245. // copy back and deinterleave
  246. for (i = mh; i < lh; i+=2, j++)
  247. t[w*lp + j] = ((l[i] * I_LFTG_X) + (1 << 16)) >> 17;
  248. for (i = 1-mh; i < lh; i+=2, j++)
  249. t[w*lp + j] = ((l[i] * I_LFTG_K) + (1 << 16)) >> 17;
  250. }
  251. }
  252. }
  253. static void sr_1d53(int *p, int i0, int i1)
  254. {
  255. int i;
  256. if (i1 <= i0 + 1) {
  257. if (i0 == 1)
  258. p[1] >>= 1;
  259. return;
  260. }
  261. extend53(p, i0, i1);
  262. for (i = i0 / 2; i < i1 / 2 + 1; i++)
  263. p[2 * i] -= (p[2 * i - 1] + p[2 * i + 1] + 2) >> 2;
  264. for (i = i0 / 2; i < i1 / 2; i++)
  265. p[2 * i + 1] += (p[2 * i] + p[2 * i + 2]) >> 1;
  266. }
  267. static void dwt_decode53(DWTContext *s, int *t)
  268. {
  269. int lev;
  270. int w = s->linelen[s->ndeclevels - 1][0];
  271. int32_t *line = s->i_linebuf;
  272. line += 3;
  273. for (lev = 0; lev < s->ndeclevels; lev++) {
  274. int lh = s->linelen[lev][0],
  275. lv = s->linelen[lev][1],
  276. mh = s->mod[lev][0],
  277. mv = s->mod[lev][1],
  278. lp;
  279. int *l;
  280. // HOR_SD
  281. l = line + mh;
  282. for (lp = 0; lp < lv; lp++) {
  283. int i, j = 0;
  284. // copy with interleaving
  285. for (i = mh; i < lh; i += 2, j++)
  286. l[i] = t[w * lp + j];
  287. for (i = 1 - mh; i < lh; i += 2, j++)
  288. l[i] = t[w * lp + j];
  289. sr_1d53(line, mh, mh + lh);
  290. for (i = 0; i < lh; i++)
  291. t[w * lp + i] = l[i];
  292. }
  293. // VER_SD
  294. l = line + mv;
  295. for (lp = 0; lp < lh; lp++) {
  296. int i, j = 0;
  297. // copy with interleaving
  298. for (i = mv; i < lv; i += 2, j++)
  299. l[i] = t[w * j + lp];
  300. for (i = 1 - mv; i < lv; i += 2, j++)
  301. l[i] = t[w * j + lp];
  302. sr_1d53(line, mv, mv + lv);
  303. for (i = 0; i < lv; i++)
  304. t[w * i + lp] = l[i];
  305. }
  306. }
  307. }
  308. static void sr_1d97_float(float *p, int i0, int i1)
  309. {
  310. int i;
  311. if (i1 <= i0 + 1) {
  312. if (i0 == 1)
  313. p[1] *= F_LFTG_K/2;
  314. else
  315. p[0] *= F_LFTG_X/2;
  316. return;
  317. }
  318. extend97_float(p, i0, i1);
  319. for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
  320. p[2 * i] -= F_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]);
  321. /* step 4 */
  322. for (i = i0 / 2 - 1; i < i1 / 2 + 1; i++)
  323. p[2 * i + 1] -= F_LFTG_GAMMA * (p[2 * i] + p[2 * i + 2]);
  324. /*step 5*/
  325. for (i = i0 / 2; i < i1 / 2 + 1; i++)
  326. p[2 * i] += F_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]);
  327. /* step 6 */
  328. for (i = i0 / 2; i < i1 / 2; i++)
  329. p[2 * i + 1] += F_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]);
  330. }
  331. static void dwt_decode97_float(DWTContext *s, float *t)
  332. {
  333. int lev;
  334. int w = s->linelen[s->ndeclevels - 1][0];
  335. float *line = s->f_linebuf;
  336. float *data = t;
  337. /* position at index O of line range [0-5,w+5] cf. extend function */
  338. line += 5;
  339. for (lev = 0; lev < s->ndeclevels; lev++) {
  340. int lh = s->linelen[lev][0],
  341. lv = s->linelen[lev][1],
  342. mh = s->mod[lev][0],
  343. mv = s->mod[lev][1],
  344. lp;
  345. float *l;
  346. // HOR_SD
  347. l = line + mh;
  348. for (lp = 0; lp < lv; lp++) {
  349. int i, j = 0;
  350. // copy with interleaving
  351. for (i = mh; i < lh; i += 2, j++)
  352. l[i] = data[w * lp + j] * F_LFTG_K;
  353. for (i = 1 - mh; i < lh; i += 2, j++)
  354. l[i] = data[w * lp + j] * F_LFTG_X;
  355. sr_1d97_float(line, mh, mh + lh);
  356. for (i = 0; i < lh; i++)
  357. data[w * lp + i] = l[i];
  358. }
  359. // VER_SD
  360. l = line + mv;
  361. for (lp = 0; lp < lh; lp++) {
  362. int i, j = 0;
  363. // copy with interleaving
  364. for (i = mv; i < lv; i += 2, j++)
  365. l[i] = data[w * j + lp] * F_LFTG_K;
  366. for (i = 1 - mv; i < lv; i += 2, j++)
  367. l[i] = data[w * j + lp] * F_LFTG_X;
  368. sr_1d97_float(line, mv, mv + lv);
  369. for (i = 0; i < lv; i++)
  370. data[w * i + lp] = l[i];
  371. }
  372. }
  373. }
  374. static void sr_1d97_int(int32_t *p, int i0, int i1)
  375. {
  376. int i;
  377. if (i1 <= i0 + 1) {
  378. if (i0 == 1)
  379. p[1] = (p[1] * I_LFTG_K + (1<<16)) >> 17;
  380. else
  381. p[0] = (p[0] * I_LFTG_X + (1<<16)) >> 17;
  382. return;
  383. }
  384. extend97_int(p, i0, i1);
  385. for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
  386. p[2 * i] -= (I_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
  387. /* step 4 */
  388. for (i = i0 / 2 - 1; i < i1 / 2 + 1; i++)
  389. p[2 * i + 1] -= (I_LFTG_GAMMA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16;
  390. /*step 5*/
  391. for (i = i0 / 2; i < i1 / 2 + 1; i++)
  392. p[2 * i] += (I_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
  393. /* step 6 */
  394. for (i = i0 / 2; i < i1 / 2; i++)
  395. p[2 * i + 1] += (I_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16;
  396. }
  397. static void dwt_decode97_int(DWTContext *s, int32_t *t)
  398. {
  399. int lev;
  400. int w = s->linelen[s->ndeclevels - 1][0];
  401. int32_t *line = s->i_linebuf;
  402. int32_t *data = t;
  403. /* position at index O of line range [0-5,w+5] cf. extend function */
  404. line += 5;
  405. for (lev = 0; lev < s->ndeclevels; lev++) {
  406. int lh = s->linelen[lev][0],
  407. lv = s->linelen[lev][1],
  408. mh = s->mod[lev][0],
  409. mv = s->mod[lev][1],
  410. lp;
  411. int32_t *l;
  412. // HOR_SD
  413. l = line + mh;
  414. for (lp = 0; lp < lv; lp++) {
  415. int i, j = 0;
  416. // rescale with interleaving
  417. for (i = mh; i < lh; i += 2, j++)
  418. l[i] = ((data[w * lp + j] * I_LFTG_K) + (1 << 15)) >> 16;
  419. for (i = 1 - mh; i < lh; i += 2, j++)
  420. l[i] = ((data[w * lp + j] * I_LFTG_X) + (1 << 15)) >> 16;
  421. sr_1d97_int(line, mh, mh + lh);
  422. for (i = 0; i < lh; i++)
  423. data[w * lp + i] = l[i];
  424. }
  425. // VER_SD
  426. l = line + mv;
  427. for (lp = 0; lp < lh; lp++) {
  428. int i, j = 0;
  429. // rescale with interleaving
  430. for (i = mv; i < lv; i += 2, j++)
  431. l[i] = ((data[w * j + lp] * I_LFTG_K) + (1 << 15)) >> 16;
  432. for (i = 1 - mv; i < lv; i += 2, j++)
  433. l[i] = ((data[w * j + lp] * I_LFTG_X) + (1 << 15)) >> 16;
  434. sr_1d97_int(line, mv, mv + lv);
  435. for (i = 0; i < lv; i++)
  436. data[w * i + lp] = l[i];
  437. }
  438. }
  439. }
  440. int ff_jpeg2000_dwt_init(DWTContext *s, uint16_t border[2][2],
  441. int decomp_levels, int type)
  442. {
  443. int i, j, lev = decomp_levels, maxlen,
  444. b[2][2];
  445. s->ndeclevels = decomp_levels;
  446. s->type = type;
  447. for (i = 0; i < 2; i++)
  448. for (j = 0; j < 2; j++)
  449. b[i][j] = border[i][j];
  450. maxlen = FFMAX(b[0][1] - b[0][0],
  451. b[1][1] - b[1][0]);
  452. while (--lev >= 0)
  453. for (i = 0; i < 2; i++) {
  454. s->linelen[lev][i] = b[i][1] - b[i][0];
  455. s->mod[lev][i] = b[i][0] & 1;
  456. for (j = 0; j < 2; j++)
  457. b[i][j] = (b[i][j] + 1) >> 1;
  458. }
  459. switch (type) {
  460. case FF_DWT97:
  461. s->f_linebuf = av_malloc_array((maxlen + 12), sizeof(*s->f_linebuf));
  462. if (!s->f_linebuf)
  463. return AVERROR(ENOMEM);
  464. break;
  465. case FF_DWT97_INT:
  466. s->i_linebuf = av_malloc_array((maxlen + 12), sizeof(*s->i_linebuf));
  467. if (!s->i_linebuf)
  468. return AVERROR(ENOMEM);
  469. break;
  470. case FF_DWT53:
  471. s->i_linebuf = av_malloc_array((maxlen + 6), sizeof(*s->i_linebuf));
  472. if (!s->i_linebuf)
  473. return AVERROR(ENOMEM);
  474. break;
  475. default:
  476. return -1;
  477. }
  478. return 0;
  479. }
  480. int ff_dwt_encode(DWTContext *s, void *t)
  481. {
  482. switch(s->type){
  483. case FF_DWT97:
  484. dwt_encode97_float(s, t); break;
  485. case FF_DWT97_INT:
  486. dwt_encode97_int(s, t); break;
  487. case FF_DWT53:
  488. dwt_encode53(s, t); break;
  489. default:
  490. return -1;
  491. }
  492. return 0;
  493. }
  494. int ff_dwt_decode(DWTContext *s, void *t)
  495. {
  496. switch (s->type) {
  497. case FF_DWT97:
  498. dwt_decode97_float(s, t);
  499. break;
  500. case FF_DWT97_INT:
  501. dwt_decode97_int(s, t);
  502. break;
  503. case FF_DWT53:
  504. dwt_decode53(s, t);
  505. break;
  506. default:
  507. return -1;
  508. }
  509. return 0;
  510. }
  511. void ff_dwt_destroy(DWTContext *s)
  512. {
  513. av_freep(&s->f_linebuf);
  514. av_freep(&s->i_linebuf);
  515. }
  516. #ifdef TEST
  517. #include "libavutil/lfg.h"
  518. #define MAX_W 256
  519. static int test_dwt(int *array, int *ref, uint16_t border[2][2], int decomp_levels, int type, int max_diff) {
  520. int ret, j;
  521. DWTContext s1={{{0}}}, *s= &s1;
  522. ret = ff_jpeg2000_dwt_init(s, border, decomp_levels, type);
  523. if (ret < 0) {
  524. fprintf(stderr, "ff_jpeg2000_dwt_init failed\n");
  525. return 1;
  526. }
  527. ret = ff_dwt_encode(s, array);
  528. if (ret < 0) {
  529. fprintf(stderr, "ff_dwt_encode failed\n");
  530. return 1;
  531. }
  532. ret = ff_dwt_decode(s, array);
  533. if (ret < 0) {
  534. fprintf(stderr, "ff_dwt_encode failed\n");
  535. return 1;
  536. }
  537. for (j = 0; j<MAX_W * MAX_W; j++) {
  538. if (FFABS(array[j] - ref[j]) > max_diff) {
  539. fprintf(stderr, "missmatch at %d (%d != %d) decomp:%d border %d %d %d %d\n",
  540. j, array[j], ref[j],decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1]);
  541. return 2;
  542. }
  543. array[j] = ref[j];
  544. }
  545. ff_dwt_destroy(s);
  546. return 0;
  547. }
  548. int main(void) {
  549. int array[MAX_W * MAX_W];
  550. int ref [MAX_W * MAX_W];
  551. AVLFG prng;
  552. int i,j;
  553. uint16_t border[2][2];
  554. int ret, decomp_levels;
  555. av_lfg_init(&prng, 1);
  556. for (i = 0; i<MAX_W * MAX_W; i++)
  557. array[i] = ref[i] = av_lfg_get(&prng) % 2048;
  558. for (i = 0; i < 40; i++) {
  559. for (j=0; j<4; j++)
  560. border[j>>1][j&1] = av_lfg_get(&prng) % MAX_W;
  561. if (border[0][0] >= border[0][1] || border[1][0] >= border[1][1])
  562. continue;
  563. decomp_levels = av_lfg_get(&prng) % FF_DWT_MAX_DECLVLS;
  564. ret = test_dwt(array, ref, border, decomp_levels, FF_DWT53, 0);
  565. if (ret)
  566. return ret;
  567. ret = test_dwt(array, ref, border, decomp_levels, FF_DWT97_INT, FFMIN(7+5*decomp_levels, 15+3*decomp_levels));
  568. if (ret)
  569. return ret;
  570. }
  571. return 0;
  572. }
  573. #endif