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.

723 lines
20KB

  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. /* Lifting parameters in integer format.
  38. * Computed as param = (float param) * (1 << 16) */
  39. #define I_LFTG_ALPHA 103949
  40. #define I_LFTG_BETA 3472
  41. #define I_LFTG_GAMMA 57862
  42. #define I_LFTG_DELTA 29066
  43. #define I_LFTG_K 80621
  44. #define I_LFTG_X 53274
  45. static inline void extend53(int *p, int i0, int i1)
  46. {
  47. p[i0 - 1] = p[i0 + 1];
  48. p[i1] = p[i1 - 2];
  49. p[i0 - 2] = p[i0 + 2];
  50. p[i1 + 1] = p[i1 - 3];
  51. }
  52. static inline void extend97_float(float *p, int i0, int i1)
  53. {
  54. int i;
  55. for (i = 1; i <= 4; i++) {
  56. p[i0 - i] = p[i0 + i];
  57. p[i1 + i - 1] = p[i1 - i - 1];
  58. }
  59. }
  60. static inline void extend97_int(int32_t *p, int i0, int i1)
  61. {
  62. int i;
  63. for (i = 1; i <= 4; i++) {
  64. p[i0 - i] = p[i0 + i];
  65. p[i1 + i - 1] = p[i1 - i - 1];
  66. }
  67. }
  68. static void sd_1d53(int *p, int i0, int i1)
  69. {
  70. int i;
  71. if (i1 <= i0 + 1) {
  72. if (i0 == 1)
  73. p[1] <<= 1;
  74. return;
  75. }
  76. extend53(p, i0, i1);
  77. for (i = (i0+1)/2 - 1; i < (i1+1)/2; i++)
  78. p[2*i+1] -= (p[2*i] + p[2*i+2]) >> 1;
  79. for (i = (i0+1)/2; i < (i1+1)/2; i++)
  80. p[2*i] += (p[2*i-1] + p[2*i+1] + 2) >> 2;
  81. }
  82. static void dwt_encode53(DWTContext *s, int *t)
  83. {
  84. int lev,
  85. w = s->linelen[s->ndeclevels-1][0];
  86. int *line = s->i_linebuf;
  87. line += 3;
  88. for (lev = s->ndeclevels-1; lev >= 0; lev--){
  89. int lh = s->linelen[lev][0],
  90. lv = s->linelen[lev][1],
  91. mh = s->mod[lev][0],
  92. mv = s->mod[lev][1],
  93. lp;
  94. int *l;
  95. // VER_SD
  96. l = line + mv;
  97. for (lp = 0; lp < lh; lp++) {
  98. int i, j = 0;
  99. for (i = 0; i < lv; i++)
  100. l[i] = t[w*i + lp];
  101. sd_1d53(line, mv, mv + lv);
  102. // copy back and deinterleave
  103. for (i = mv; i < lv; i+=2, j++)
  104. t[w*j + lp] = l[i];
  105. for (i = 1-mv; i < lv; i+=2, j++)
  106. t[w*j + lp] = l[i];
  107. }
  108. // HOR_SD
  109. l = line + mh;
  110. for (lp = 0; lp < lv; lp++){
  111. int i, j = 0;
  112. for (i = 0; i < lh; i++)
  113. l[i] = t[w*lp + i];
  114. sd_1d53(line, mh, mh + lh);
  115. // copy back and deinterleave
  116. for (i = mh; i < lh; i+=2, j++)
  117. t[w*lp + j] = l[i];
  118. for (i = 1-mh; i < lh; i+=2, j++)
  119. t[w*lp + j] = l[i];
  120. }
  121. }
  122. }
  123. static void sd_1d97_float(float *p, int i0, int i1)
  124. {
  125. int i;
  126. if (i1 <= i0 + 1) {
  127. if (i0 == 1)
  128. p[1] *= F_LFTG_X * 2;
  129. else
  130. p[0] *= F_LFTG_K;
  131. return;
  132. }
  133. extend97_float(p, i0, i1);
  134. i0++; i1++;
  135. for (i = i0/2 - 2; i < i1/2 + 1; i++)
  136. p[2*i+1] -= 1.586134 * (p[2*i] + p[2*i+2]);
  137. for (i = i0/2 - 1; i < i1/2 + 1; i++)
  138. p[2*i] -= 0.052980 * (p[2*i-1] + p[2*i+1]);
  139. for (i = i0/2 - 1; i < i1/2; i++)
  140. p[2*i+1] += 0.882911 * (p[2*i] + p[2*i+2]);
  141. for (i = i0/2; i < i1/2; i++)
  142. p[2*i] += 0.443506 * (p[2*i-1] + p[2*i+1]);
  143. }
  144. static void dwt_encode97_float(DWTContext *s, float *t)
  145. {
  146. int lev,
  147. w = s->linelen[s->ndeclevels-1][0];
  148. float *line = s->f_linebuf;
  149. line += 5;
  150. for (lev = s->ndeclevels-1; lev >= 0; lev--){
  151. int lh = s->linelen[lev][0],
  152. lv = s->linelen[lev][1],
  153. mh = s->mod[lev][0],
  154. mv = s->mod[lev][1],
  155. lp;
  156. float *l;
  157. // HOR_SD
  158. l = line + mh;
  159. for (lp = 0; lp < lv; lp++){
  160. int i, j = 0;
  161. for (i = 0; i < lh; i++)
  162. l[i] = t[w*lp + i];
  163. sd_1d97_float(line, mh, mh + lh);
  164. // copy back and deinterleave
  165. for (i = mh; i < lh; i+=2, j++)
  166. t[w*lp + j] = F_LFTG_X * l[i];
  167. for (i = 1-mh; i < lh; i+=2, j++)
  168. t[w*lp + j] = F_LFTG_K * l[i];
  169. }
  170. // VER_SD
  171. l = line + mv;
  172. for (lp = 0; lp < lh; lp++) {
  173. int i, j = 0;
  174. for (i = 0; i < lv; i++)
  175. l[i] = t[w*i + lp];
  176. sd_1d97_float(line, mv, mv + lv);
  177. // copy back and deinterleave
  178. for (i = mv; i < lv; i+=2, j++)
  179. t[w*j + lp] = F_LFTG_X * l[i];
  180. for (i = 1-mv; i < lv; i+=2, j++)
  181. t[w*j + lp] = F_LFTG_K * l[i];
  182. }
  183. }
  184. }
  185. static void sd_1d97_int(int *p, int i0, int i1)
  186. {
  187. int i;
  188. if (i1 <= i0 + 1) {
  189. if (i0 == 1)
  190. p[1] = (p[1] * I_LFTG_X + (1<<14)) >> 15;
  191. else
  192. p[0] = (p[0] * I_LFTG_K + (1<<15)) >> 16;
  193. return;
  194. }
  195. extend97_int(p, i0, i1);
  196. i0++; i1++;
  197. for (i = i0/2 - 2; i < i1/2 + 1; i++)
  198. p[2 * i + 1] -= (I_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16;
  199. for (i = i0/2 - 1; i < i1/2 + 1; i++)
  200. p[2 * i] -= (I_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
  201. for (i = i0/2 - 1; i < i1/2; i++)
  202. p[2 * i + 1] += (I_LFTG_GAMMA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16;
  203. for (i = i0/2; i < i1/2; i++)
  204. p[2 * i] += (I_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
  205. }
  206. static void dwt_encode97_int(DWTContext *s, int *t)
  207. {
  208. int lev,
  209. w = s->linelen[s->ndeclevels-1][0];
  210. int *line = s->i_linebuf;
  211. line += 5;
  212. for (lev = s->ndeclevels-1; lev >= 0; lev--){
  213. int lh = s->linelen[lev][0],
  214. lv = s->linelen[lev][1],
  215. mh = s->mod[lev][0],
  216. mv = s->mod[lev][1],
  217. lp;
  218. int *l;
  219. // VER_SD
  220. l = line + mv;
  221. for (lp = 0; lp < lh; lp++) {
  222. int i, j = 0;
  223. for (i = 0; i < lv; i++)
  224. l[i] = t[w*i + lp];
  225. sd_1d97_int(line, mv, mv + lv);
  226. // copy back and deinterleave
  227. for (i = mv; i < lv; i+=2, j++)
  228. t[w*j + lp] = ((l[i] * I_LFTG_X) + (1 << 15)) >> 16;
  229. for (i = 1-mv; i < lv; i+=2, j++)
  230. t[w*j + lp] = ((l[i] * I_LFTG_K) + (1 << 15)) >> 16;
  231. }
  232. // HOR_SD
  233. l = line + mh;
  234. for (lp = 0; lp < lv; lp++){
  235. int i, j = 0;
  236. for (i = 0; i < lh; i++)
  237. l[i] = t[w*lp + i];
  238. sd_1d97_int(line, mh, mh + lh);
  239. // copy back and deinterleave
  240. for (i = mh; i < lh; i+=2, j++)
  241. t[w*lp + j] = ((l[i] * I_LFTG_X) + (1 << 15)) >> 16;
  242. for (i = 1-mh; i < lh; i+=2, j++)
  243. t[w*lp + j] = ((l[i] * I_LFTG_K) + (1 << 15)) >> 16;
  244. }
  245. }
  246. }
  247. static void sr_1d53(int *p, int i0, int i1)
  248. {
  249. int i;
  250. if (i1 <= i0 + 1) {
  251. if (i0 == 1)
  252. p[1] >>= 1;
  253. return;
  254. }
  255. extend53(p, i0, i1);
  256. for (i = i0 / 2; i < i1 / 2 + 1; i++)
  257. p[2 * i] -= (p[2 * i - 1] + p[2 * i + 1] + 2) >> 2;
  258. for (i = i0 / 2; i < i1 / 2; i++)
  259. p[2 * i + 1] += (p[2 * i] + p[2 * i + 2]) >> 1;
  260. }
  261. static void dwt_decode53(DWTContext *s, int *t)
  262. {
  263. int lev;
  264. int w = s->linelen[s->ndeclevels - 1][0];
  265. int32_t *line = s->i_linebuf;
  266. line += 3;
  267. for (lev = 0; lev < s->ndeclevels; lev++) {
  268. int lh = s->linelen[lev][0],
  269. lv = s->linelen[lev][1],
  270. mh = s->mod[lev][0],
  271. mv = s->mod[lev][1],
  272. lp;
  273. int *l;
  274. // HOR_SD
  275. l = line + mh;
  276. for (lp = 0; lp < lv; lp++) {
  277. int i, j = 0;
  278. // copy with interleaving
  279. for (i = mh; i < lh; i += 2, j++)
  280. l[i] = t[w * lp + j];
  281. for (i = 1 - mh; i < lh; i += 2, j++)
  282. l[i] = t[w * lp + j];
  283. sr_1d53(line, mh, mh + lh);
  284. for (i = 0; i < lh; i++)
  285. t[w * lp + i] = l[i];
  286. }
  287. // VER_SD
  288. l = line + mv;
  289. for (lp = 0; lp < lh; lp++) {
  290. int i, j = 0;
  291. // copy with interleaving
  292. for (i = mv; i < lv; i += 2, j++)
  293. l[i] = t[w * j + lp];
  294. for (i = 1 - mv; i < lv; i += 2, j++)
  295. l[i] = t[w * j + lp];
  296. sr_1d53(line, mv, mv + lv);
  297. for (i = 0; i < lv; i++)
  298. t[w * i + lp] = l[i];
  299. }
  300. }
  301. }
  302. static void sr_1d97_float(float *p, int i0, int i1)
  303. {
  304. int i;
  305. if (i1 <= i0 + 1) {
  306. if (i0 == 1)
  307. p[1] *= F_LFTG_K/2;
  308. else
  309. p[0] *= F_LFTG_X;
  310. return;
  311. }
  312. extend97_float(p, i0, i1);
  313. for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
  314. p[2 * i] -= F_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]);
  315. /* step 4 */
  316. for (i = i0 / 2 - 1; i < i1 / 2 + 1; i++)
  317. p[2 * i + 1] -= F_LFTG_GAMMA * (p[2 * i] + p[2 * i + 2]);
  318. /*step 5*/
  319. for (i = i0 / 2; i < i1 / 2 + 1; i++)
  320. p[2 * i] += F_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]);
  321. /* step 6 */
  322. for (i = i0 / 2; i < i1 / 2; i++)
  323. p[2 * i + 1] += F_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]);
  324. }
  325. static void dwt_decode97_float(DWTContext *s, float *t)
  326. {
  327. int lev;
  328. int w = s->linelen[s->ndeclevels - 1][0];
  329. float *line = s->f_linebuf;
  330. float *data = t;
  331. /* position at index O of line range [0-5,w+5] cf. extend function */
  332. line += 5;
  333. for (lev = 0; lev < s->ndeclevels; lev++) {
  334. int lh = s->linelen[lev][0],
  335. lv = s->linelen[lev][1],
  336. mh = s->mod[lev][0],
  337. mv = s->mod[lev][1],
  338. lp;
  339. float *l;
  340. // HOR_SD
  341. l = line + mh;
  342. for (lp = 0; lp < lv; lp++) {
  343. int i, j = 0;
  344. // copy with interleaving
  345. for (i = mh; i < lh; i += 2, j++)
  346. l[i] = data[w * lp + j] * F_LFTG_K;
  347. for (i = 1 - mh; i < lh; i += 2, j++)
  348. l[i] = data[w * lp + j] * F_LFTG_X;
  349. sr_1d97_float(line, mh, mh + lh);
  350. for (i = 0; i < lh; i++)
  351. data[w * lp + i] = l[i];
  352. }
  353. // VER_SD
  354. l = line + mv;
  355. for (lp = 0; lp < lh; lp++) {
  356. int i, j = 0;
  357. // copy with interleaving
  358. for (i = mv; i < lv; i += 2, j++)
  359. l[i] = data[w * j + lp] * F_LFTG_K;
  360. for (i = 1 - mv; i < lv; i += 2, j++)
  361. l[i] = data[w * j + lp] * F_LFTG_X;
  362. sr_1d97_float(line, mv, mv + lv);
  363. for (i = 0; i < lv; i++)
  364. data[w * i + lp] = l[i];
  365. }
  366. }
  367. }
  368. static void sr_1d97_int(int32_t *p, int i0, int i1)
  369. {
  370. int i;
  371. if (i1 <= i0 + 1) {
  372. if (i0 == 1)
  373. p[1] = (p[1] * I_LFTG_K + (1<<16)) >> 17;
  374. else
  375. p[0] = (p[0] * I_LFTG_X + (1<<15)) >> 16;
  376. return;
  377. }
  378. extend97_int(p, i0, i1);
  379. for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
  380. p[2 * i] -= (I_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
  381. /* step 4 */
  382. for (i = i0 / 2 - 1; i < i1 / 2 + 1; i++)
  383. p[2 * i + 1] -= (I_LFTG_GAMMA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16;
  384. /*step 5*/
  385. for (i = i0 / 2; i < i1 / 2 + 1; i++)
  386. p[2 * i] += (I_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
  387. /* step 6 */
  388. for (i = i0 / 2; i < i1 / 2; i++)
  389. p[2 * i + 1] += (I_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16;
  390. }
  391. static void dwt_decode97_int(DWTContext *s, int32_t *t)
  392. {
  393. int lev;
  394. int w = s->linelen[s->ndeclevels - 1][0];
  395. int32_t *line = s->i_linebuf;
  396. int32_t *data = t;
  397. /* position at index O of line range [0-5,w+5] cf. extend function */
  398. line += 5;
  399. for (lev = 0; lev < s->ndeclevels; lev++) {
  400. int lh = s->linelen[lev][0],
  401. lv = s->linelen[lev][1],
  402. mh = s->mod[lev][0],
  403. mv = s->mod[lev][1],
  404. lp;
  405. int32_t *l;
  406. // HOR_SD
  407. l = line + mh;
  408. for (lp = 0; lp < lv; lp++) {
  409. int i, j = 0;
  410. // rescale with interleaving
  411. for (i = mh; i < lh; i += 2, j++)
  412. l[i] = ((data[w * lp + j] * I_LFTG_K) + (1 << 15)) >> 16;
  413. for (i = 1 - mh; i < lh; i += 2, j++)
  414. l[i] = ((data[w * lp + j] * I_LFTG_X) + (1 << 15)) >> 16;
  415. sr_1d97_int(line, mh, mh + lh);
  416. for (i = 0; i < lh; i++)
  417. data[w * lp + i] = l[i];
  418. }
  419. // VER_SD
  420. l = line + mv;
  421. for (lp = 0; lp < lh; lp++) {
  422. int i, j = 0;
  423. // rescale with interleaving
  424. for (i = mv; i < lv; i += 2, j++)
  425. l[i] = ((data[w * j + lp] * I_LFTG_K) + (1 << 15)) >> 16;
  426. for (i = 1 - mv; i < lv; i += 2, j++)
  427. l[i] = ((data[w * j + lp] * I_LFTG_X) + (1 << 15)) >> 16;
  428. sr_1d97_int(line, mv, mv + lv);
  429. for (i = 0; i < lv; i++)
  430. data[w * i + lp] = l[i];
  431. }
  432. }
  433. }
  434. int ff_jpeg2000_dwt_init(DWTContext *s, uint16_t border[2][2],
  435. int decomp_levels, int type)
  436. {
  437. int i, j, lev = decomp_levels, maxlen,
  438. b[2][2];
  439. s->ndeclevels = decomp_levels;
  440. s->type = type;
  441. for (i = 0; i < 2; i++)
  442. for (j = 0; j < 2; j++)
  443. b[i][j] = border[i][j];
  444. maxlen = FFMAX(b[0][1] - b[0][0],
  445. b[1][1] - b[1][0]);
  446. while (--lev >= 0)
  447. for (i = 0; i < 2; i++) {
  448. s->linelen[lev][i] = b[i][1] - b[i][0];
  449. s->mod[lev][i] = b[i][0] & 1;
  450. for (j = 0; j < 2; j++)
  451. b[i][j] = (b[i][j] + 1) >> 1;
  452. }
  453. switch (type) {
  454. case FF_DWT97:
  455. s->f_linebuf = av_malloc_array((maxlen + 12), sizeof(*s->f_linebuf));
  456. if (!s->f_linebuf)
  457. return AVERROR(ENOMEM);
  458. break;
  459. case FF_DWT97_INT:
  460. s->i_linebuf = av_malloc_array((maxlen + 12), sizeof(*s->i_linebuf));
  461. if (!s->i_linebuf)
  462. return AVERROR(ENOMEM);
  463. break;
  464. case FF_DWT53:
  465. s->i_linebuf = av_malloc_array((maxlen + 6), sizeof(*s->i_linebuf));
  466. if (!s->i_linebuf)
  467. return AVERROR(ENOMEM);
  468. break;
  469. default:
  470. return -1;
  471. }
  472. return 0;
  473. }
  474. int ff_dwt_encode(DWTContext *s, void *t)
  475. {
  476. switch(s->type){
  477. case FF_DWT97:
  478. dwt_encode97_float(s, t); break;
  479. case FF_DWT97_INT:
  480. dwt_encode97_int(s, t); break;
  481. case FF_DWT53:
  482. dwt_encode53(s, t); break;
  483. default:
  484. return -1;
  485. }
  486. return 0;
  487. }
  488. int ff_dwt_decode(DWTContext *s, void *t)
  489. {
  490. switch (s->type) {
  491. case FF_DWT97:
  492. dwt_decode97_float(s, t);
  493. break;
  494. case FF_DWT97_INT:
  495. dwt_decode97_int(s, t);
  496. break;
  497. case FF_DWT53:
  498. dwt_decode53(s, t);
  499. break;
  500. default:
  501. return -1;
  502. }
  503. return 0;
  504. }
  505. void ff_dwt_destroy(DWTContext *s)
  506. {
  507. av_freep(&s->f_linebuf);
  508. av_freep(&s->i_linebuf);
  509. }
  510. #ifdef TEST
  511. #include "libavutil/lfg.h"
  512. #define MAX_W 256
  513. static int test_dwt(int *array, int *ref, uint16_t border[2][2], int decomp_levels, int type, int max_diff) {
  514. int ret, j;
  515. DWTContext s1={{{0}}}, *s= &s1;
  516. int64_t err2 = 0;
  517. ret = ff_jpeg2000_dwt_init(s, border, decomp_levels, type);
  518. if (ret < 0) {
  519. fprintf(stderr, "ff_jpeg2000_dwt_init failed\n");
  520. return 1;
  521. }
  522. ret = ff_dwt_encode(s, array);
  523. if (ret < 0) {
  524. fprintf(stderr, "ff_dwt_encode failed\n");
  525. return 1;
  526. }
  527. ret = ff_dwt_decode(s, array);
  528. if (ret < 0) {
  529. fprintf(stderr, "ff_dwt_encode failed\n");
  530. return 1;
  531. }
  532. for (j = 0; j<MAX_W * MAX_W; j++) {
  533. if (FFABS(array[j] - ref[j]) > max_diff) {
  534. fprintf(stderr, "missmatch at %d (%d != %d) decomp:%d border %d %d %d %d\n",
  535. j, array[j], ref[j],decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1]);
  536. return 2;
  537. }
  538. err2 += (array[j] - ref[j]) * (array[j] - ref[j]);
  539. array[j] = ref[j];
  540. }
  541. ff_dwt_destroy(s);
  542. printf("%s, decomp:%2d border %3d %3d %3d %3d milli-err2:%9"PRId64"\n",
  543. type == FF_DWT53 ? "5/3i" : "9/7i",
  544. decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1],
  545. 1000*err2 / ((border[0][1] - border[0][0])*(border[1][1] - border[1][0])));
  546. return 0;
  547. }
  548. static int test_dwtf(float *array, float *ref, uint16_t border[2][2], int decomp_levels, float max_diff) {
  549. int ret, j;
  550. DWTContext s1={{{0}}}, *s= &s1;
  551. double err2 = 0;
  552. ret = ff_jpeg2000_dwt_init(s, border, decomp_levels, FF_DWT97);
  553. if (ret < 0) {
  554. fprintf(stderr, "ff_jpeg2000_dwt_init failed\n");
  555. return 1;
  556. }
  557. ret = ff_dwt_encode(s, array);
  558. if (ret < 0) {
  559. fprintf(stderr, "ff_dwt_encode failed\n");
  560. return 1;
  561. }
  562. ret = ff_dwt_decode(s, array);
  563. if (ret < 0) {
  564. fprintf(stderr, "ff_dwt_encode failed\n");
  565. return 1;
  566. }
  567. for (j = 0; j<MAX_W * MAX_W; j++) {
  568. if (FFABS(array[j] - ref[j]) > max_diff) {
  569. fprintf(stderr, "missmatch at %d (%f != %f) decomp:%d border %d %d %d %d\n",
  570. j, array[j], ref[j],decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1]);
  571. return 2;
  572. }
  573. err2 += (array[j] - ref[j]) * (array[j] - ref[j]);
  574. array[j] = ref[j];
  575. }
  576. ff_dwt_destroy(s);
  577. printf("9/7f, decomp:%2d border %3d %3d %3d %3d err2:%20.4f\n",
  578. decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1],
  579. err2 / ((border[0][1] - border[0][0])*(border[1][1] - border[1][0])));
  580. return 0;
  581. }
  582. int main(void) {
  583. int array[MAX_W * MAX_W];
  584. int ref [MAX_W * MAX_W];
  585. float arrayf[MAX_W * MAX_W];
  586. float reff [MAX_W * MAX_W];
  587. AVLFG prng;
  588. int i,j;
  589. uint16_t border[2][2];
  590. int ret, decomp_levels;
  591. av_lfg_init(&prng, 1);
  592. for (i = 0; i<MAX_W * MAX_W; i++)
  593. arrayf[i] = reff[i] = array[i] = ref[i] = av_lfg_get(&prng) % 2048;
  594. for (i = 0; i < 100; i++) {
  595. for (j=0; j<4; j++)
  596. border[j>>1][j&1] = av_lfg_get(&prng) % MAX_W;
  597. if (border[0][0] >= border[0][1] || border[1][0] >= border[1][1])
  598. continue;
  599. decomp_levels = av_lfg_get(&prng) % FF_DWT_MAX_DECLVLS;
  600. ret = test_dwt(array, ref, border, decomp_levels, FF_DWT53, 0);
  601. if (ret)
  602. return ret;
  603. ret = test_dwt(array, ref, border, decomp_levels, FF_DWT97_INT, FFMIN(7+5*decomp_levels, 15+3*decomp_levels));
  604. if (ret)
  605. return ret;
  606. ret = test_dwtf(arrayf, reff, border, decomp_levels, 1.0);
  607. if (ret)
  608. return ret;
  609. }
  610. return 0;
  611. }
  612. #endif