/schroedinger-1.0.11/schroedinger/schrofilter.c

# · C · 987 lines · 821 code · 160 blank · 6 comment · 68 complexity · 877afc874387c832c1a953e0040fac21 MD5 · raw file

  1. #ifdef HAVE_CONFIG_H
  2. #include "config.h"
  3. #endif
  4. #include <schroedinger/schrofilter.h>
  5. #include <schroedinger/schrodebug.h>
  6. #include <schroedinger/schrowavelet.h>
  7. #include <schroedinger/schrotables.h>
  8. #include <schroedinger/schrobitstream.h>
  9. #include <schroedinger/schrohistogram.h>
  10. #include <schroedinger/schroparams.h>
  11. #include <schroedinger/schrovirtframe.h>
  12. #include <string.h>
  13. #include <math.h>
  14. static void
  15. sort_u8 (uint8_t * d, int n)
  16. {
  17. int start = 0;
  18. int end = n;
  19. int i;
  20. int x;
  21. /* OMG bubble sort! */
  22. while (start < end) {
  23. for (i = start; i < end - 1; i++) {
  24. if (d[i] > d[i + 1]) {
  25. x = d[i];
  26. d[i] = d[i + 1];
  27. d[i + 1] = x;
  28. }
  29. }
  30. end--;
  31. for (i = end - 2; i >= start; i--) {
  32. if (d[i] > d[i + 1]) {
  33. x = d[i];
  34. d[i] = d[i + 1];
  35. d[i + 1] = x;
  36. }
  37. }
  38. start++;
  39. }
  40. }
  41. #ifdef unused
  42. /* reference */
  43. void
  44. schro_filter_cwmN_ref (uint8_t * d, uint8_t * s1, uint8_t * s2, uint8_t * s3,
  45. int n, int weight)
  46. {
  47. int i;
  48. int j;
  49. uint8_t list[8 + 12];
  50. for (i = 0; i < n; i++) {
  51. list[0] = s1[i + 0];
  52. list[1] = s1[i + 1];
  53. list[2] = s1[i + 2];
  54. list[3] = s2[i + 0];
  55. list[4] = s2[i + 2];
  56. list[5] = s3[i + 0];
  57. list[6] = s3[i + 1];
  58. list[7] = s3[i + 2];
  59. for (j = 0; j < weight; j++) {
  60. list[8 + j] = s2[i + 1];
  61. }
  62. sort_u8 (list, 8 + weight);
  63. d[i] = list[(8 + weight) / 2];
  64. }
  65. }
  66. #endif
  67. void
  68. schro_filter_cwmN (uint8_t * d, uint8_t * s1, uint8_t * s2, uint8_t * s3, int n,
  69. int weight)
  70. {
  71. int i;
  72. int j;
  73. uint8_t list[8 + 12];
  74. int low, hi;
  75. for (i = 0; i < n; i++) {
  76. list[0] = s1[i + 0];
  77. list[1] = s1[i + 1];
  78. list[2] = s1[i + 2];
  79. list[3] = s2[i + 0];
  80. list[4] = s2[i + 2];
  81. list[5] = s3[i + 0];
  82. list[6] = s3[i + 1];
  83. list[7] = s3[i + 2];
  84. low = 0;
  85. hi = 0;
  86. for (j = 0; j < 8; j++) {
  87. if (list[j] < s2[i + 1])
  88. low++;
  89. if (list[j] > s2[i + 1])
  90. hi++;
  91. }
  92. if (low < ((9 - weight) / 2) || hi < ((9 - weight) / 2)) {
  93. for (j = 0; j < weight; j++) {
  94. list[8 + j] = s2[i + 1];
  95. }
  96. sort_u8 (list, 8 + weight);
  97. d[i] = list[(8 + weight) / 2];
  98. } else {
  99. d[i] = s2[i + 1];
  100. }
  101. }
  102. }
  103. static void
  104. schro_frame_component_filter_cwmN (SchroFrameData * comp, int weight)
  105. {
  106. int i;
  107. uint8_t *tmp;
  108. uint8_t *tmp1;
  109. uint8_t *tmp2;
  110. tmp1 = schro_malloc (comp->width);
  111. tmp2 = schro_malloc (comp->width);
  112. schro_filter_cwmN (tmp1,
  113. OFFSET (comp->data, comp->stride * 0),
  114. OFFSET (comp->data, comp->stride * 1),
  115. OFFSET (comp->data, comp->stride * 2), comp->width - 2, weight);
  116. schro_filter_cwmN (tmp2,
  117. OFFSET (comp->data, comp->stride * 1),
  118. OFFSET (comp->data, comp->stride * 2),
  119. OFFSET (comp->data, comp->stride * 3), comp->width - 2, weight);
  120. for (i = 3; i < comp->height - 1; i++) {
  121. memcpy (OFFSET (comp->data, comp->stride * (i - 2) + 1),
  122. tmp1, comp->width - 2);
  123. tmp = tmp1;
  124. tmp1 = tmp2;
  125. tmp2 = tmp;
  126. schro_filter_cwmN (tmp2,
  127. OFFSET (comp->data, comp->stride * (i - 1)),
  128. OFFSET (comp->data, comp->stride * (i + 0)),
  129. OFFSET (comp->data, comp->stride * (i + 1)), comp->width - 2, weight);
  130. }
  131. memcpy (OFFSET (comp->data, comp->stride * (i - 2) + 1),
  132. tmp1, comp->width - 2);
  133. memcpy (OFFSET (comp->data, comp->stride * (i - 1) + 1),
  134. tmp2, comp->width - 2);
  135. schro_free (tmp1);
  136. schro_free (tmp2);
  137. }
  138. void
  139. schro_frame_filter_cwmN (SchroFrame * frame, int weight)
  140. {
  141. schro_frame_component_filter_cwmN (&frame->components[0], weight);
  142. schro_frame_component_filter_cwmN (&frame->components[1], weight);
  143. schro_frame_component_filter_cwmN (&frame->components[2], weight);
  144. }
  145. #ifdef unused
  146. static void
  147. schro_frame_component_filter_cwmN_ref (SchroFrameData * comp, int weight)
  148. {
  149. int i;
  150. uint8_t *tmp;
  151. uint8_t *tmp1;
  152. uint8_t *tmp2;
  153. tmp1 = schro_malloc (comp->width);
  154. tmp2 = schro_malloc (comp->width);
  155. schro_filter_cwmN_ref (tmp1,
  156. OFFSET (comp->data, comp->stride * 0),
  157. OFFSET (comp->data, comp->stride * 1),
  158. OFFSET (comp->data, comp->stride * 2), comp->width - 2, weight);
  159. schro_filter_cwmN_ref (tmp2,
  160. OFFSET (comp->data, comp->stride * 1),
  161. OFFSET (comp->data, comp->stride * 2),
  162. OFFSET (comp->data, comp->stride * 3), comp->width - 2, weight);
  163. for (i = 3; i < comp->height - 1; i++) {
  164. memcpy (OFFSET (comp->data, comp->stride * (i - 2) + 1),
  165. tmp1, comp->width - 2);
  166. tmp = tmp1;
  167. tmp1 = tmp2;
  168. tmp2 = tmp;
  169. schro_filter_cwmN_ref (tmp2,
  170. OFFSET (comp->data, comp->stride * (i - 1)),
  171. OFFSET (comp->data, comp->stride * (i + 0)),
  172. OFFSET (comp->data, comp->stride * (i + 1)), comp->width - 2, weight);
  173. }
  174. memcpy (OFFSET (comp->data, comp->stride * (i - 2) + 1),
  175. tmp1, comp->width - 2);
  176. memcpy (OFFSET (comp->data, comp->stride * (i - 1) + 1),
  177. tmp2, comp->width - 2);
  178. schro_free (tmp1);
  179. schro_free (tmp2);
  180. }
  181. #endif
  182. #ifdef unused
  183. void
  184. schro_frame_filter_cwmN_ref (SchroFrame * frame, int weight)
  185. {
  186. schro_frame_component_filter_cwmN_ref (&frame->components[0], weight);
  187. schro_frame_component_filter_cwmN_ref (&frame->components[1], weight);
  188. schro_frame_component_filter_cwmN_ref (&frame->components[2], weight);
  189. }
  190. #endif
  191. #if 0
  192. /* reference */
  193. void
  194. schro_filter_cwm7 (uint8_t * d, uint8_t * s1, uint8_t * s2, uint8_t * s3, int n)
  195. {
  196. int i;
  197. int min, max;
  198. for (i = 0; i < n; i++) {
  199. min = MIN (s1[i + 0], s1[i + 1]);
  200. max = MAX (s1[i + 0], s1[i + 1]);
  201. min = MIN (min, s1[i + 2]);
  202. max = MAX (max, s1[i + 2]);
  203. min = MIN (min, s2[i + 0]);
  204. max = MAX (max, s2[i + 0]);
  205. min = MIN (min, s2[i + 2]);
  206. max = MAX (max, s2[i + 2]);
  207. min = MIN (min, s3[i + 0]);
  208. max = MAX (max, s3[i + 0]);
  209. min = MIN (min, s3[i + 1]);
  210. max = MAX (max, s3[i + 1]);
  211. min = MIN (min, s3[i + 2]);
  212. max = MAX (max, s3[i + 2]);
  213. d[i] = MIN (max, MAX (min, s2[i + 1]));
  214. }
  215. }
  216. #endif
  217. #ifdef unused
  218. /* FIXME move to schrooil */
  219. void
  220. schro_filter_cwm7 (uint8_t * d, uint8_t * s1, uint8_t * s2, uint8_t * s3, int n)
  221. {
  222. int i;
  223. int min, max;
  224. for (i = 0; i < n; i++) {
  225. if (s1[i + 0] < s2[i + 1]) {
  226. max = MAX (s1[i + 0], s1[i + 1]);
  227. max = MAX (max, s1[i + 2]);
  228. max = MAX (max, s2[i + 0]);
  229. max = MAX (max, s2[i + 2]);
  230. max = MAX (max, s3[i + 0]);
  231. max = MAX (max, s3[i + 1]);
  232. max = MAX (max, s3[i + 2]);
  233. d[i] = MIN (max, s2[i + 1]);
  234. } else if (s1[i + 0] > s2[i + 1]) {
  235. min = MIN (s1[i + 0], s1[i + 1]);
  236. min = MIN (min, s1[i + 2]);
  237. min = MIN (min, s2[i + 0]);
  238. min = MIN (min, s2[i + 2]);
  239. min = MIN (min, s3[i + 0]);
  240. min = MIN (min, s3[i + 1]);
  241. min = MIN (min, s3[i + 2]);
  242. d[i] = MAX (min, s2[i + 1]);
  243. } else {
  244. d[i] = s2[i + 1];
  245. }
  246. }
  247. }
  248. #endif
  249. #ifdef unused
  250. static void
  251. schro_frame_component_filter_cwm7 (SchroFrameData * comp)
  252. {
  253. int i;
  254. uint8_t *tmp;
  255. uint8_t *tmp1;
  256. uint8_t *tmp2;
  257. tmp1 = schro_malloc (comp->width);
  258. tmp2 = schro_malloc (comp->width);
  259. schro_filter_cwm7 (tmp1,
  260. OFFSET (comp->data, comp->stride * 0),
  261. OFFSET (comp->data, comp->stride * 1),
  262. OFFSET (comp->data, comp->stride * 2), comp->width - 2);
  263. schro_filter_cwm7 (tmp2,
  264. OFFSET (comp->data, comp->stride * 1),
  265. OFFSET (comp->data, comp->stride * 2),
  266. OFFSET (comp->data, comp->stride * 3), comp->width - 2);
  267. for (i = 3; i < comp->height - 1; i++) {
  268. memcpy (OFFSET (comp->data, comp->stride * (i - 2) + 1),
  269. tmp1, comp->width - 2);
  270. tmp = tmp1;
  271. tmp1 = tmp2;
  272. tmp2 = tmp;
  273. schro_filter_cwm7 (tmp2,
  274. OFFSET (comp->data, comp->stride * (i - 1)),
  275. OFFSET (comp->data, comp->stride * (i + 0)),
  276. OFFSET (comp->data, comp->stride * (i + 1)), comp->width - 2);
  277. }
  278. memcpy (OFFSET (comp->data, comp->stride * (i - 2) + 1),
  279. tmp1, comp->width - 2);
  280. memcpy (OFFSET (comp->data, comp->stride * (i - 1) + 1),
  281. tmp2, comp->width - 2);
  282. schro_free (tmp1);
  283. schro_free (tmp2);
  284. }
  285. #endif
  286. #ifdef unused
  287. void
  288. schro_frame_filter_cwm7 (SchroFrame * frame)
  289. {
  290. schro_frame_component_filter_cwm7 (&frame->components[0]);
  291. schro_frame_component_filter_cwm7 (&frame->components[1]);
  292. schro_frame_component_filter_cwm7 (&frame->components[2]);
  293. }
  294. #endif
  295. static void
  296. lowpass3_h_u8 (SchroFrame *frame, void *_dest, int component, int i)
  297. {
  298. uint8_t *dest = _dest;
  299. uint8_t *src;
  300. int tap1, tap2;
  301. tap1 = *(int *)frame->virt_priv2;
  302. tap2 = 256 - 2*tap1;
  303. src = schro_virt_frame_get_line (frame->virt_frame1, component, i);
  304. if (component > 0) {
  305. memcpy (dest, src, frame->components[component].width);
  306. return;
  307. }
  308. i = 0;
  309. dest[i] = (src[i] * tap1 + src[i] * tap2 + src[i+1] * tap1 + 128)>>8;
  310. for(i=1;i<frame->width-1;i++) {
  311. dest[i] = (src[i-1] * tap1 + src[i] * tap2 + src[i+1] * tap1 + 128)>>8;
  312. }
  313. i = frame->width - 1;
  314. dest[i] = (src[i-1] * tap1 + src[i] * tap2 + src[i] * tap1 + 128)>>8;
  315. }
  316. static void
  317. lowpass3_v_u8 (SchroFrame *frame, void *_dest, int component, int i)
  318. {
  319. uint8_t *dest = _dest;
  320. uint8_t *src1, *src2, *src3;
  321. int tap1, tap2;
  322. if (component > 0) {
  323. src2 = schro_virt_frame_get_line (frame->virt_frame1, component, i);
  324. memcpy (dest, src2, frame->components[component].width);
  325. return;
  326. }
  327. tap1 = *(int *)frame->virt_priv2;
  328. tap2 = 256 - 2*tap1;
  329. src1 = schro_virt_frame_get_line (frame->virt_frame1, component,
  330. CLAMP(i-1,0,frame->height));
  331. src2 = schro_virt_frame_get_line (frame->virt_frame1, component, i);
  332. src3 = schro_virt_frame_get_line (frame->virt_frame1, component,
  333. CLAMP(i+1,0,frame->height));
  334. for(i=0;i<frame->width;i++) {
  335. dest[i] = (src1[i] * tap1 + src2[i] * tap2 + src3[i] * tap1 + 128)>>8;
  336. }
  337. }
  338. void
  339. schro_frame_filter_lowpass (SchroFrame * frame, int tap)
  340. {
  341. SchroFrame *vf;
  342. SchroFrame *vf2;
  343. SchroFrame *dup;
  344. dup = schro_frame_dup (frame);
  345. vf = schro_frame_new_virtual (NULL, frame->format, frame->width, frame->height);
  346. vf->virt_frame1 = schro_frame_ref(frame);
  347. vf->render_line = lowpass3_h_u8;
  348. vf->virt_priv2 = (void *) &tap;
  349. vf2 = schro_frame_new_virtual (NULL, frame->format, frame->width, frame->height);
  350. vf2->virt_frame1 = vf;
  351. vf2->render_line = lowpass3_v_u8;
  352. vf2->virt_priv2 = (void *) &tap;
  353. schro_virt_frame_render (vf2, dup);
  354. schro_frame_convert (frame, dup);
  355. schro_frame_unref (vf2);
  356. schro_frame_unref (dup);
  357. }
  358. #ifdef unused
  359. static void
  360. lowpass_s16 (int16_t * d, int16_t * s, int n)
  361. {
  362. int i;
  363. int j;
  364. int x;
  365. const int32_t taps[] = { 2, 9, 28, 55, 68, 55, 28, 9, 2, 0 };
  366. const int32_t offsetshift[] = { 128, 8 };
  367. for (i = 0; i < 4; i++) {
  368. x = 0;
  369. for (j = 0; j < 9; j++) {
  370. x += s[CLAMP (i + j - 4, 0, n - 1)] * taps[j];
  371. }
  372. d[i] = (x + 128) >> 8;
  373. }
  374. schro_mas10_s16 (d + 4, s, taps, offsetshift, n - 9);
  375. for (i = n - 6; i < n; i++) {
  376. x = 0;
  377. for (j = 0; j < 9; j++) {
  378. x += s[CLAMP (i + j - 4, 0, n - 1)] * taps[j];
  379. }
  380. d[i] = (x + 128) >> 8;
  381. }
  382. }
  383. #endif
  384. #ifdef unused
  385. /* FIXME move to schrooil */
  386. static void
  387. lowpass_vert_s16 (int16_t * d, int16_t * s, int n)
  388. {
  389. int i;
  390. int j;
  391. int x;
  392. static int taps[] = { 2, 9, 28, 55, 68, 55, 28, 9, 2, 0 };
  393. for (i = 0; i < n; i++) {
  394. x = 0;
  395. for (j = 0; j < 9; j++) {
  396. x += s[j * n + i] * taps[j];
  397. }
  398. d[i] = (x + 128) >> 8;
  399. }
  400. }
  401. #endif
  402. #ifdef unused
  403. static void
  404. schro_frame_component_filter_lowpass_16 (SchroFrameData * comp)
  405. {
  406. int i;
  407. int16_t *tmp;
  408. tmp = schro_malloc (comp->width * 9 * sizeof (int16_t));
  409. lowpass_s16 (tmp + 0 * comp->width,
  410. OFFSET (comp->data, comp->stride * 0), comp->width);
  411. memcpy (tmp + 1 * comp->width, tmp + 0 * comp->width, comp->width * 2);
  412. memcpy (tmp + 2 * comp->width, tmp + 0 * comp->width, comp->width * 2);
  413. memcpy (tmp + 3 * comp->width, tmp + 0 * comp->width, comp->width * 2);
  414. memcpy (tmp + 4 * comp->width, tmp + 0 * comp->width, comp->width * 2);
  415. lowpass_s16 (tmp + 5 * comp->width,
  416. OFFSET (comp->data, comp->stride * 1), comp->width);
  417. lowpass_s16 (tmp + 6 * comp->width,
  418. OFFSET (comp->data, comp->stride * 2), comp->width);
  419. lowpass_s16 (tmp + 7 * comp->width,
  420. OFFSET (comp->data, comp->stride * 3), comp->width);
  421. for (i = 0; i < comp->height; i++) {
  422. lowpass_s16 (tmp + 8 * comp->width,
  423. OFFSET (comp->data, comp->stride * CLAMP (i + 4, 0, comp->height - 1)),
  424. comp->width);
  425. lowpass_vert_s16 (OFFSET (comp->data, comp->stride * i), tmp, comp->width);
  426. memmove (tmp, tmp + comp->width * 1, comp->width * 8 * sizeof (int16_t));
  427. }
  428. schro_free (tmp);
  429. }
  430. #endif
  431. #ifdef unused
  432. void
  433. schro_frame_filter_lowpass_16 (SchroFrame * frame)
  434. {
  435. schro_frame_component_filter_lowpass_16 (&frame->components[0]);
  436. schro_frame_component_filter_lowpass_16 (&frame->components[1]);
  437. schro_frame_component_filter_lowpass_16 (&frame->components[2]);
  438. }
  439. #endif
  440. static void
  441. schro_convert_f64_u8 (double *dest, uint8_t * src, int n)
  442. {
  443. int i;
  444. for (i = 0; i < n; i++) {
  445. dest[i] = src[i];
  446. }
  447. }
  448. static void
  449. schro_iir3_s16_f64 (int16_t * d, int16_t * s, double *i_3, double *s2_4, int n)
  450. {
  451. int i;
  452. for (i = 0; i < n; i++) {
  453. double x;
  454. x = s2_4[0] * s[i] + s2_4[1] * i_3[0] + s2_4[2] * i_3[1] + s2_4[3] * i_3[2];
  455. i_3[2] = i_3[1];
  456. i_3[1] = i_3[0];
  457. i_3[0] = x;
  458. d[i] = rint (x);
  459. }
  460. }
  461. static void
  462. schro_iir3_rev_s16_f64 (int16_t * d, int16_t * s, double *i_3, double *s2_4,
  463. int n)
  464. {
  465. int i;
  466. for (i = n - 1; i >= 0; i--) {
  467. double x;
  468. x = s2_4[0] * s[i] + s2_4[1] * i_3[0] + s2_4[2] * i_3[1] + s2_4[3] * i_3[2];
  469. i_3[2] = i_3[1];
  470. i_3[1] = i_3[0];
  471. i_3[0] = x;
  472. d[i] = rint (x);
  473. }
  474. }
  475. static void
  476. schro_iir3_across_u8_f64 (uint8_t * d, uint8_t * s, double *i1, double *i2,
  477. double *i3, double *s2_4, int n)
  478. {
  479. int i;
  480. for (i = 0; i < n; i++) {
  481. double x;
  482. x = s2_4[0] * s[i] + s2_4[1] * i1[i] + s2_4[2] * i2[i] + s2_4[3] * i3[i];
  483. i3[i] = i2[i];
  484. i2[i] = i1[i];
  485. i1[i] = x;
  486. d[i] = rint (x);
  487. }
  488. }
  489. static void
  490. schro_iir3_across_s16_f64 (int16_t * d, int16_t * s, double *i1, double *i2,
  491. double *i3, double *s2_4, int n)
  492. {
  493. int i;
  494. for (i = 0; i < n; i++) {
  495. double x;
  496. x = s2_4[0] * s[i] + s2_4[1] * i1[i] + s2_4[2] * i2[i] + s2_4[3] * i3[i];
  497. i3[i] = i2[i];
  498. i2[i] = i1[i];
  499. i1[i] = x;
  500. d[i] = rint (x);
  501. }
  502. }
  503. static void
  504. schro_convert_f64_s16 (double *dest, int16_t * src, int n)
  505. {
  506. int i;
  507. for (i = 0; i < n; i++) {
  508. dest[i] = src[i];
  509. }
  510. }
  511. static void
  512. schro_iir3_u8_f64 (uint8_t * d, uint8_t * s, double *i_3, double *s2_4, int n)
  513. {
  514. int i;
  515. for (i = 0; i < n; i++) {
  516. double x;
  517. x = s2_4[0] * s[i] + s2_4[1] * i_3[0] + s2_4[2] * i_3[1] + s2_4[3] * i_3[2];
  518. i_3[2] = i_3[1];
  519. i_3[1] = i_3[0];
  520. i_3[0] = x;
  521. d[i] = rint (x);
  522. }
  523. }
  524. static void
  525. schro_iir3_rev_u8_f64 (uint8_t * d, uint8_t * s, double *i_3, double *s2_4,
  526. int n)
  527. {
  528. int i;
  529. for (i = n - 1; i >= 0; i--) {
  530. double x;
  531. x = s2_4[0] * s[i] + s2_4[1] * i_3[0] + s2_4[2] * i_3[1] + s2_4[3] * i_3[2];
  532. i_3[2] = i_3[1];
  533. i_3[1] = i_3[0];
  534. i_3[0] = x;
  535. d[i] = rint (x);
  536. }
  537. }
  538. static void
  539. lowpass2_u8 (uint8_t * d, uint8_t * s, double *coeff, int n)
  540. {
  541. double state[3];
  542. state[0] = s[0];
  543. state[1] = s[0];
  544. state[2] = s[0];
  545. schro_iir3_u8_f64 (d, s, state, coeff, n);
  546. state[0] = d[n - 1];
  547. state[1] = d[n - 1];
  548. state[2] = d[n - 1];
  549. schro_iir3_rev_u8_f64 (d, s, state, coeff, n);
  550. }
  551. static void
  552. lowpass2_s16 (int16_t * d, int16_t * s, double *coeff, int n)
  553. {
  554. double state[3];
  555. state[0] = s[0];
  556. state[1] = s[0];
  557. state[2] = s[0];
  558. schro_iir3_s16_f64 (d, s, state, coeff, n);
  559. state[0] = d[n - 1];
  560. state[1] = d[n - 1];
  561. state[2] = d[n - 1];
  562. schro_iir3_rev_s16_f64 (d, s, state, coeff, n);
  563. }
  564. static void
  565. generate_coeff (double *coeff, double sigma)
  566. {
  567. double q;
  568. double b0, b0inv, b1, b2, b3, B;
  569. if (sigma >= 2.5) {
  570. q = 0.98711 * sigma - 0.96330;
  571. } else {
  572. q = 3.97156 - 4.41554 * sqrt (1 - 0.26891 * sigma);
  573. }
  574. b0 = 1.57825 + 2.44413 * q + 1.4281 * q * q + 0.422205 * q * q * q;
  575. b0inv = 1.0 / b0;
  576. b1 = 2.44413 * q + 2.85619 * q * q + 1.26661 * q * q * q;
  577. b2 = -1.4281 * q * q - 1.26661 * q * q * q;
  578. b3 = 0.422205 * q * q * q;
  579. B = 1 - (b1 + b2 + b3) / b0;
  580. coeff[0] = B;
  581. coeff[1] = b1 * b0inv;
  582. coeff[2] = b2 * b0inv;
  583. coeff[3] = b3 * b0inv;
  584. }
  585. static void
  586. schro_frame_component_filter_lowpass2_u8 (SchroFrameData * comp,
  587. double h_sigma, double v_sigma)
  588. {
  589. int i;
  590. double h_coeff[4];
  591. double v_coeff[4];
  592. double *i1, *i2, *i3;
  593. generate_coeff (h_coeff, h_sigma);
  594. generate_coeff (v_coeff, v_sigma);
  595. i1 = schro_malloc (sizeof (double) * comp->width);
  596. i2 = schro_malloc (sizeof (double) * comp->width);
  597. i3 = schro_malloc (sizeof (double) * comp->width);
  598. for (i = 0; i < comp->height; i++) {
  599. lowpass2_u8 (OFFSET (comp->data, comp->stride * i),
  600. OFFSET (comp->data, comp->stride * i), h_coeff, comp->width);
  601. }
  602. schro_convert_f64_u8 (i1, OFFSET (comp->data, comp->stride * 0), comp->width);
  603. memcpy (i2, i1, sizeof (double) * comp->width);
  604. memcpy (i3, i1, sizeof (double) * comp->width);
  605. for (i = 0; i < comp->height; i++) {
  606. schro_iir3_across_u8_f64 (OFFSET (comp->data, comp->stride * i),
  607. OFFSET (comp->data, comp->stride * i),
  608. i1, i2, i3, v_coeff, comp->width);
  609. }
  610. schro_convert_f64_u8 (i1, OFFSET (comp->data,
  611. comp->stride * (comp->height - 1)), comp->width);
  612. memcpy (i2, i1, sizeof (double) * comp->width);
  613. memcpy (i3, i1, sizeof (double) * comp->width);
  614. for (i = comp->height - 1; i >= 0; i--) {
  615. schro_iir3_across_u8_f64 (OFFSET (comp->data, comp->stride * i),
  616. OFFSET (comp->data, comp->stride * i),
  617. i1, i2, i3, v_coeff, comp->width);
  618. }
  619. schro_free (i1);
  620. schro_free (i2);
  621. schro_free (i3);
  622. }
  623. static void
  624. schro_frame_component_filter_lowpass2_s16 (SchroFrameData * comp,
  625. double h_sigma, double v_sigma)
  626. {
  627. int i;
  628. double h_coeff[4];
  629. double v_coeff[4];
  630. double *i1, *i2, *i3;
  631. generate_coeff (h_coeff, h_sigma);
  632. generate_coeff (v_coeff, v_sigma);
  633. i1 = schro_malloc (sizeof (double) * comp->width);
  634. i2 = schro_malloc (sizeof (double) * comp->width);
  635. i3 = schro_malloc (sizeof (double) * comp->width);
  636. for (i = 0; i < comp->height; i++) {
  637. lowpass2_s16 (OFFSET (comp->data, comp->stride * i),
  638. OFFSET (comp->data, comp->stride * i), h_coeff, comp->width);
  639. }
  640. schro_convert_f64_s16 (i1, OFFSET (comp->data, comp->stride * 0),
  641. comp->width);
  642. memcpy (i2, i1, sizeof (double) * comp->width);
  643. memcpy (i3, i1, sizeof (double) * comp->width);
  644. for (i = 0; i < comp->height; i++) {
  645. schro_iir3_across_s16_f64 (OFFSET (comp->data, comp->stride * i),
  646. OFFSET (comp->data, comp->stride * i),
  647. i1, i2, i3, v_coeff, comp->width);
  648. }
  649. schro_convert_f64_s16 (i1, OFFSET (comp->data,
  650. comp->stride * (comp->height - 1)), comp->width);
  651. memcpy (i2, i1, sizeof (double) * comp->width);
  652. memcpy (i3, i1, sizeof (double) * comp->width);
  653. for (i = comp->height - 1; i >= 0; i--) {
  654. schro_iir3_across_s16_f64 (OFFSET (comp->data, comp->stride * i),
  655. OFFSET (comp->data, comp->stride * i),
  656. i1, i2, i3, v_coeff, comp->width);
  657. }
  658. schro_free (i1);
  659. schro_free (i2);
  660. schro_free (i3);
  661. }
  662. void
  663. schro_frame_filter_lowpass2 (SchroFrame * frame, double sigma)
  664. {
  665. double chroma_sigma_h;
  666. double chroma_sigma_v;
  667. chroma_sigma_h = sigma / (1 << SCHRO_FRAME_FORMAT_H_SHIFT (frame->format));
  668. chroma_sigma_v = sigma / (1 << SCHRO_FRAME_FORMAT_V_SHIFT (frame->format));
  669. switch (SCHRO_FRAME_FORMAT_DEPTH (frame->format)) {
  670. case SCHRO_FRAME_FORMAT_DEPTH_U8:
  671. schro_frame_component_filter_lowpass2_u8 (&frame->components[0], sigma,
  672. sigma);
  673. schro_frame_component_filter_lowpass2_u8 (&frame->components[1],
  674. chroma_sigma_h, chroma_sigma_v);
  675. schro_frame_component_filter_lowpass2_u8 (&frame->components[2],
  676. chroma_sigma_h, chroma_sigma_v);
  677. break;
  678. case SCHRO_FRAME_FORMAT_DEPTH_S16:
  679. schro_frame_component_filter_lowpass2_s16 (&frame->components[0], sigma,
  680. sigma);
  681. schro_frame_component_filter_lowpass2_s16 (&frame->components[1],
  682. chroma_sigma_h, chroma_sigma_v);
  683. schro_frame_component_filter_lowpass2_s16 (&frame->components[2],
  684. chroma_sigma_h, chroma_sigma_v);
  685. break;
  686. default:
  687. SCHRO_ASSERT (0);
  688. break;
  689. }
  690. }
  691. #ifdef unused
  692. void
  693. schro_frame_filter_wavelet (SchroFrame * frame)
  694. {
  695. SchroFrame *tmpframe;
  696. SchroFrameData *comp;
  697. SchroHistogram hist;
  698. int component;
  699. int16_t *tmp;
  700. SchroParams params;
  701. int i;
  702. tmp = schro_malloc (2 * frame->width * sizeof (int16_t));
  703. tmpframe = schro_frame_new_and_alloc (NULL,
  704. SCHRO_FRAME_FORMAT_S16_444 | frame->format,
  705. ROUND_UP_POW2 (frame->width, 5), ROUND_UP_POW2 (frame->height, 5));
  706. schro_frame_convert (tmpframe, frame);
  707. params.transform_depth = 1;
  708. params.iwt_luma_width = frame->width;
  709. params.iwt_luma_height = frame->height;
  710. params.iwt_chroma_width = frame->components[1].width;
  711. params.iwt_chroma_height = frame->components[1].height;
  712. for (component = 0; component < 3; component++) {
  713. comp = &tmpframe->components[component];
  714. schro_wavelet_transform_2d (comp, SCHRO_WAVELET_LE_GALL_5_3, tmp);
  715. for (i = 1; i < 4; i++) {
  716. SchroFrameData fd;
  717. int y;
  718. int cutoff;
  719. schro_subband_get_frame_data (&fd, tmpframe, component, i, &params);
  720. schro_histogram_init (&hist);
  721. for (y = 0; y < fd.height; y++) {
  722. schro_histogram_add_array_s16 (&hist, OFFSET (fd.data, y * fd.stride),
  723. fd.width);
  724. }
  725. cutoff = 100;
  726. for (y = 0; y < fd.height; y++) {
  727. int16_t *line = OFFSET (fd.data, fd.stride * y);
  728. int x;
  729. for (x = 0; x < fd.width; x++) {
  730. if (line[x] > -cutoff && line[x] < cutoff)
  731. line[x] = 0;
  732. }
  733. }
  734. }
  735. schro_wavelet_inverse_transform_2d (comp, SCHRO_WAVELET_LE_GALL_5_3, tmp);
  736. }
  737. schro_frame_convert (frame, tmpframe);
  738. schro_frame_unref (tmpframe);
  739. }
  740. #endif
  741. static double
  742. random_std (void)
  743. {
  744. double x;
  745. double y;
  746. while (1) {
  747. x = -5.0 + rand () * (1.0 / RAND_MAX) * 10;
  748. y = rand () * (1.0 / RAND_MAX);
  749. if (y < exp (-x * x * 0.5))
  750. return x;
  751. }
  752. }
  753. static void
  754. addnoise_u8 (uint8_t * dest, int n, double sigma)
  755. {
  756. int i;
  757. int x;
  758. for (i = 0; i < n; i++) {
  759. x = rint (random_std () * sigma) + dest[i];
  760. dest[i] = CLAMP (x, 0, 255);
  761. }
  762. }
  763. static void
  764. schro_frame_component_filter_addnoise (SchroFrameData * comp, double sigma)
  765. {
  766. int i;
  767. for (i = 0; i < comp->height; i++) {
  768. addnoise_u8 (OFFSET (comp->data, comp->stride * i), comp->width, sigma);
  769. }
  770. }
  771. void
  772. schro_frame_filter_addnoise (SchroFrame * frame, double sigma)
  773. {
  774. schro_frame_component_filter_addnoise (&frame->components[0], sigma);
  775. schro_frame_component_filter_addnoise (&frame->components[1], sigma);
  776. schro_frame_component_filter_addnoise (&frame->components[2], sigma);
  777. }
  778. static int
  779. ilogx_size (int i)
  780. {
  781. if (i < (1 << SCHRO_HISTOGRAM_SHIFT))
  782. return 1;
  783. return 1 << ((i >> SCHRO_HISTOGRAM_SHIFT) - 1);
  784. }
  785. static int
  786. iexpx (int x)
  787. {
  788. if (x < (1 << SCHRO_HISTOGRAM_SHIFT))
  789. return x;
  790. return ((1 << SCHRO_HISTOGRAM_SHIFT) | (x & ((1 << SCHRO_HISTOGRAM_SHIFT) -
  791. 1))) << ((x >> SCHRO_HISTOGRAM_SHIFT) - 1);
  792. }
  793. void
  794. schro_frame_filter_adaptive_lowpass (SchroFrame * frame)
  795. {
  796. SchroHistogram hist;
  797. double slope;
  798. SchroFrame *tmp;
  799. int16_t tmpdata[2048];
  800. double sigma;
  801. int j;
  802. int i;
  803. tmp = schro_frame_new_and_alloc (NULL,
  804. SCHRO_FRAME_FORMAT_S16_444 | frame->format, frame->width, frame->height);
  805. schro_frame_convert (tmp, frame);
  806. schro_wavelet_transform_2d (&tmp->components[0], SCHRO_WAVELET_LE_GALL_5_3,
  807. tmpdata);
  808. schro_histogram_init (&hist);
  809. for (j = 0; j < tmp->height / 2; j++) {
  810. schro_histogram_add_array_s16 (&hist,
  811. OFFSET (tmp->components[0].data,
  812. tmp->components[0].stride * (2 * j + 1)), tmp->width / 2);
  813. }
  814. schro_frame_unref (tmp);
  815. tmp = NULL;
  816. slope = schro_histogram_estimate_slope (&hist);
  817. for (i = 0; i < SCHRO_HISTOGRAM_SIZE; i++) {
  818. schro_dump (SCHRO_DUMP_HIST_TEST, "%d %g\n",
  819. iexpx (i), hist.bins[i] / ilogx_size (i));
  820. }
  821. /* good for 2 Mb DVD intra-only rip */
  822. sigma = -1.0 / slope;
  823. if (sigma > 1.0) {
  824. SCHRO_DEBUG ("enabling filtering (slope %g)", slope);
  825. schro_frame_filter_lowpass2 (frame, sigma);
  826. }
  827. }