6 #include <schroedinger/schrofilter.h>
7 #include <schroedinger/schrodebug.h>
8 #include <schroedinger/schrowavelet.h>
9 #include <schroedinger/schrotables.h>
10 #include <schroedinger/schrobitstream.h>
11 #include <schroedinger/schrohistogram.h>
12 #include <schroedinger/schroparams.h>
13 #include <schroedinger/schrovirtframe.h>
19 sort_u8 (uint8_t * d
, int n
)
26 /* OMG bubble sort! */
28 for (i
= start
; i
< end
- 1; i
++) {
29 if (d
[i
] > d
[i
+ 1]) {
36 for (i
= end
- 2; i
>= start
; i
--) {
37 if (d
[i
] > d
[i
+ 1]) {
50 schro_filter_cwmN_ref (uint8_t * d
, uint8_t * s1
, uint8_t * s2
, uint8_t * s3
,
57 for (i
= 0; i
< n
; i
++) {
66 for (j
= 0; j
< weight
; j
++) {
67 list
[8 + j
] = s2
[i
+ 1];
70 sort_u8 (list
, 8 + weight
);
72 d
[i
] = list
[(8 + weight
) / 2];
78 schro_filter_cwmN (uint8_t * d
, uint8_t * s1
, uint8_t * s2
, uint8_t * s3
, int n
,
86 for (i
= 0; i
< n
; i
++) {
98 for (j
= 0; j
< 8; j
++) {
99 if (list
[j
] < s2
[i
+ 1])
101 if (list
[j
] > s2
[i
+ 1])
105 if (low
< ((9 - weight
) / 2) || hi
< ((9 - weight
) / 2)) {
106 for (j
= 0; j
< weight
; j
++) {
107 list
[8 + j
] = s2
[i
+ 1];
110 sort_u8 (list
, 8 + weight
);
112 d
[i
] = list
[(8 + weight
) / 2];
120 schro_frame_component_filter_cwmN (SchroFrameData
* comp
, int weight
)
127 tmp1
= schro_malloc (comp
->width
);
128 tmp2
= schro_malloc (comp
->width
);
130 schro_filter_cwmN (tmp1
,
131 OFFSET (comp
->data
, comp
->stride
* 0),
132 OFFSET (comp
->data
, comp
->stride
* 1),
133 OFFSET (comp
->data
, comp
->stride
* 2), comp
->width
- 2, weight
);
134 schro_filter_cwmN (tmp2
,
135 OFFSET (comp
->data
, comp
->stride
* 1),
136 OFFSET (comp
->data
, comp
->stride
* 2),
137 OFFSET (comp
->data
, comp
->stride
* 3), comp
->width
- 2, weight
);
139 for (i
= 3; i
< comp
->height
- 1; i
++) {
140 memcpy (OFFSET (comp
->data
, comp
->stride
* (i
- 2) + 1),
141 tmp1
, comp
->width
- 2);
146 schro_filter_cwmN (tmp2
,
147 OFFSET (comp
->data
, comp
->stride
* (i
- 1)),
148 OFFSET (comp
->data
, comp
->stride
* (i
+ 0)),
149 OFFSET (comp
->data
, comp
->stride
* (i
+ 1)), comp
->width
- 2, weight
);
151 memcpy (OFFSET (comp
->data
, comp
->stride
* (i
- 2) + 1),
152 tmp1
, comp
->width
- 2);
153 memcpy (OFFSET (comp
->data
, comp
->stride
* (i
- 1) + 1),
154 tmp2
, comp
->width
- 2);
161 schro_frame_filter_cwmN (SchroFrame
* frame
, int weight
)
163 schro_frame_component_filter_cwmN (&frame
->components
[0], weight
);
164 schro_frame_component_filter_cwmN (&frame
->components
[1], weight
);
165 schro_frame_component_filter_cwmN (&frame
->components
[2], weight
);
171 schro_frame_component_filter_cwmN_ref (SchroFrameData
* comp
, int weight
)
178 tmp1
= schro_malloc (comp
->width
);
179 tmp2
= schro_malloc (comp
->width
);
181 schro_filter_cwmN_ref (tmp1
,
182 OFFSET (comp
->data
, comp
->stride
* 0),
183 OFFSET (comp
->data
, comp
->stride
* 1),
184 OFFSET (comp
->data
, comp
->stride
* 2), comp
->width
- 2, weight
);
185 schro_filter_cwmN_ref (tmp2
,
186 OFFSET (comp
->data
, comp
->stride
* 1),
187 OFFSET (comp
->data
, comp
->stride
* 2),
188 OFFSET (comp
->data
, comp
->stride
* 3), comp
->width
- 2, weight
);
190 for (i
= 3; i
< comp
->height
- 1; i
++) {
191 memcpy (OFFSET (comp
->data
, comp
->stride
* (i
- 2) + 1),
192 tmp1
, comp
->width
- 2);
197 schro_filter_cwmN_ref (tmp2
,
198 OFFSET (comp
->data
, comp
->stride
* (i
- 1)),
199 OFFSET (comp
->data
, comp
->stride
* (i
+ 0)),
200 OFFSET (comp
->data
, comp
->stride
* (i
+ 1)), comp
->width
- 2, weight
);
202 memcpy (OFFSET (comp
->data
, comp
->stride
* (i
- 2) + 1),
203 tmp1
, comp
->width
- 2);
204 memcpy (OFFSET (comp
->data
, comp
->stride
* (i
- 1) + 1),
205 tmp2
, comp
->width
- 2);
214 schro_frame_filter_cwmN_ref (SchroFrame
* frame
, int weight
)
216 schro_frame_component_filter_cwmN_ref (&frame
->components
[0], weight
);
217 schro_frame_component_filter_cwmN_ref (&frame
->components
[1], weight
);
218 schro_frame_component_filter_cwmN_ref (&frame
->components
[2], weight
);
226 schro_filter_cwm7 (uint8_t * d
, uint8_t * s1
, uint8_t * s2
, uint8_t * s3
, int n
)
231 for (i
= 0; i
< n
; i
++) {
232 min
= MIN (s1
[i
+ 0], s1
[i
+ 1]);
233 max
= MAX (s1
[i
+ 0], s1
[i
+ 1]);
234 min
= MIN (min
, s1
[i
+ 2]);
235 max
= MAX (max
, s1
[i
+ 2]);
236 min
= MIN (min
, s2
[i
+ 0]);
237 max
= MAX (max
, s2
[i
+ 0]);
238 min
= MIN (min
, s2
[i
+ 2]);
239 max
= MAX (max
, s2
[i
+ 2]);
240 min
= MIN (min
, s3
[i
+ 0]);
241 max
= MAX (max
, s3
[i
+ 0]);
242 min
= MIN (min
, s3
[i
+ 1]);
243 max
= MAX (max
, s3
[i
+ 1]);
244 min
= MIN (min
, s3
[i
+ 2]);
245 max
= MAX (max
, s3
[i
+ 2]);
247 d
[i
] = MIN (max
, MAX (min
, s2
[i
+ 1]));
253 /* FIXME move to schrooil */
255 schro_filter_cwm7 (uint8_t * d
, uint8_t * s1
, uint8_t * s2
, uint8_t * s3
, int n
)
260 for (i
= 0; i
< n
; i
++) {
261 if (s1
[i
+ 0] < s2
[i
+ 1]) {
262 max
= MAX (s1
[i
+ 0], s1
[i
+ 1]);
263 max
= MAX (max
, s1
[i
+ 2]);
264 max
= MAX (max
, s2
[i
+ 0]);
265 max
= MAX (max
, s2
[i
+ 2]);
266 max
= MAX (max
, s3
[i
+ 0]);
267 max
= MAX (max
, s3
[i
+ 1]);
268 max
= MAX (max
, s3
[i
+ 2]);
269 d
[i
] = MIN (max
, s2
[i
+ 1]);
270 } else if (s1
[i
+ 0] > s2
[i
+ 1]) {
271 min
= MIN (s1
[i
+ 0], s1
[i
+ 1]);
272 min
= MIN (min
, s1
[i
+ 2]);
273 min
= MIN (min
, s2
[i
+ 0]);
274 min
= MIN (min
, s2
[i
+ 2]);
275 min
= MIN (min
, s3
[i
+ 0]);
276 min
= MIN (min
, s3
[i
+ 1]);
277 min
= MIN (min
, s3
[i
+ 2]);
278 d
[i
] = MAX (min
, s2
[i
+ 1]);
288 schro_frame_component_filter_cwm7 (SchroFrameData
* comp
)
295 tmp1
= schro_malloc (comp
->width
);
296 tmp2
= schro_malloc (comp
->width
);
298 schro_filter_cwm7 (tmp1
,
299 OFFSET (comp
->data
, comp
->stride
* 0),
300 OFFSET (comp
->data
, comp
->stride
* 1),
301 OFFSET (comp
->data
, comp
->stride
* 2), comp
->width
- 2);
302 schro_filter_cwm7 (tmp2
,
303 OFFSET (comp
->data
, comp
->stride
* 1),
304 OFFSET (comp
->data
, comp
->stride
* 2),
305 OFFSET (comp
->data
, comp
->stride
* 3), comp
->width
- 2);
307 for (i
= 3; i
< comp
->height
- 1; i
++) {
308 memcpy (OFFSET (comp
->data
, comp
->stride
* (i
- 2) + 1),
309 tmp1
, comp
->width
- 2);
314 schro_filter_cwm7 (tmp2
,
315 OFFSET (comp
->data
, comp
->stride
* (i
- 1)),
316 OFFSET (comp
->data
, comp
->stride
* (i
+ 0)),
317 OFFSET (comp
->data
, comp
->stride
* (i
+ 1)), comp
->width
- 2);
319 memcpy (OFFSET (comp
->data
, comp
->stride
* (i
- 2) + 1),
320 tmp1
, comp
->width
- 2);
321 memcpy (OFFSET (comp
->data
, comp
->stride
* (i
- 1) + 1),
322 tmp2
, comp
->width
- 2);
331 schro_frame_filter_cwm7 (SchroFrame
* frame
)
333 schro_frame_component_filter_cwm7 (&frame
->components
[0]);
334 schro_frame_component_filter_cwm7 (&frame
->components
[1]);
335 schro_frame_component_filter_cwm7 (&frame
->components
[2]);
341 lowpass3_h_u8 (SchroFrame
*frame
, void *_dest
, int component
, int i
)
343 uint8_t *dest
= _dest
;
347 tap1
= *(int *)frame
->virt_priv2
;
350 src
= schro_virt_frame_get_line (frame
->virt_frame1
, component
, i
);
353 memcpy (dest
, src
, frame
->components
[component
].width
);
358 dest
[i
] = (src
[i
] * tap1
+ src
[i
] * tap2
+ src
[i
+1] * tap1
+ 128)>>8;
360 for(i
=1;i
<frame
->width
-1;i
++) {
361 dest
[i
] = (src
[i
-1] * tap1
+ src
[i
] * tap2
+ src
[i
+1] * tap1
+ 128)>>8;
364 i
= frame
->width
- 1;
365 dest
[i
] = (src
[i
-1] * tap1
+ src
[i
] * tap2
+ src
[i
] * tap1
+ 128)>>8;
370 lowpass3_v_u8 (SchroFrame
*frame
, void *_dest
, int component
, int i
)
372 uint8_t *dest
= _dest
;
373 uint8_t *src1
, *src2
, *src3
;
377 src2
= schro_virt_frame_get_line (frame
->virt_frame1
, component
, i
);
378 memcpy (dest
, src2
, frame
->components
[component
].width
);
382 tap1
= *(int *)frame
->virt_priv2
;
385 src1
= schro_virt_frame_get_line (frame
->virt_frame1
, component
,
386 CLAMP(i
-1,0,frame
->height
));
387 src2
= schro_virt_frame_get_line (frame
->virt_frame1
, component
, i
);
388 src3
= schro_virt_frame_get_line (frame
->virt_frame1
, component
,
389 CLAMP(i
+1,0,frame
->height
));
391 for(i
=0;i
<frame
->width
;i
++) {
392 dest
[i
] = (src1
[i
] * tap1
+ src2
[i
] * tap2
+ src3
[i
] * tap1
+ 128)>>8;
398 schro_frame_filter_lowpass (SchroFrame
* frame
, int tap
)
404 dup
= schro_frame_dup (frame
);
406 vf
= schro_frame_new_virtual (NULL
, frame
->format
, frame
->width
, frame
->height
);
407 vf
->virt_frame1
= schro_frame_ref(frame
);
408 vf
->render_line
= lowpass3_h_u8
;
409 vf
->virt_priv2
= (void *) &tap
;
411 vf2
= schro_frame_new_virtual (NULL
, frame
->format
, frame
->width
, frame
->height
);
412 vf2
->virt_frame1
= vf
;
413 vf2
->render_line
= lowpass3_v_u8
;
414 vf2
->virt_priv2
= (void *) &tap
;
416 schro_virt_frame_render (vf2
, dup
);
417 schro_frame_convert (frame
, dup
);
419 schro_frame_unref (vf2
);
420 schro_frame_unref (dup
);
426 lowpass_s16 (int16_t * d
, int16_t * s
, int n
)
431 const int32_t taps
[] = { 2, 9, 28, 55, 68, 55, 28, 9, 2, 0 };
432 const int32_t offsetshift
[] = { 128, 8 };
434 for (i
= 0; i
< 4; i
++) {
436 for (j
= 0; j
< 9; j
++) {
437 x
+= s
[CLAMP (i
+ j
- 4, 0, n
- 1)] * taps
[j
];
439 d
[i
] = (x
+ 128) >> 8;
441 schro_mas10_s16 (d
+ 4, s
, taps
, offsetshift
, n
- 9);
442 for (i
= n
- 6; i
< n
; i
++) {
444 for (j
= 0; j
< 9; j
++) {
445 x
+= s
[CLAMP (i
+ j
- 4, 0, n
- 1)] * taps
[j
];
447 d
[i
] = (x
+ 128) >> 8;
453 /* FIXME move to schrooil */
455 lowpass_vert_s16 (int16_t * d
, int16_t * s
, int n
)
460 static int taps
[] = { 2, 9, 28, 55, 68, 55, 28, 9, 2, 0 };
462 for (i
= 0; i
< n
; i
++) {
464 for (j
= 0; j
< 9; j
++) {
465 x
+= s
[j
* n
+ i
] * taps
[j
];
467 d
[i
] = (x
+ 128) >> 8;
475 schro_frame_component_filter_lowpass_16 (SchroFrameData
* comp
)
480 tmp
= schro_malloc (comp
->width
* 9 * sizeof (int16_t));
482 lowpass_s16 (tmp
+ 0 * comp
->width
,
483 OFFSET (comp
->data
, comp
->stride
* 0), comp
->width
);
484 memcpy (tmp
+ 1 * comp
->width
, tmp
+ 0 * comp
->width
, comp
->width
* 2);
485 memcpy (tmp
+ 2 * comp
->width
, tmp
+ 0 * comp
->width
, comp
->width
* 2);
486 memcpy (tmp
+ 3 * comp
->width
, tmp
+ 0 * comp
->width
, comp
->width
* 2);
487 memcpy (tmp
+ 4 * comp
->width
, tmp
+ 0 * comp
->width
, comp
->width
* 2);
488 lowpass_s16 (tmp
+ 5 * comp
->width
,
489 OFFSET (comp
->data
, comp
->stride
* 1), comp
->width
);
490 lowpass_s16 (tmp
+ 6 * comp
->width
,
491 OFFSET (comp
->data
, comp
->stride
* 2), comp
->width
);
492 lowpass_s16 (tmp
+ 7 * comp
->width
,
493 OFFSET (comp
->data
, comp
->stride
* 3), comp
->width
);
494 for (i
= 0; i
< comp
->height
; i
++) {
495 lowpass_s16 (tmp
+ 8 * comp
->width
,
496 OFFSET (comp
->data
, comp
->stride
* CLAMP (i
+ 4, 0, comp
->height
- 1)),
498 lowpass_vert_s16 (OFFSET (comp
->data
, comp
->stride
* i
), tmp
, comp
->width
);
499 memmove (tmp
, tmp
+ comp
->width
* 1, comp
->width
* 8 * sizeof (int16_t));
508 schro_frame_filter_lowpass_16 (SchroFrame
* frame
)
510 schro_frame_component_filter_lowpass_16 (&frame
->components
[0]);
511 schro_frame_component_filter_lowpass_16 (&frame
->components
[1]);
512 schro_frame_component_filter_lowpass_16 (&frame
->components
[2]);
517 schro_convert_f64_u8 (double *dest
, uint8_t * src
, int n
)
520 for (i
= 0; i
< n
; i
++) {
526 schro_iir3_s16_f64 (int16_t * d
, int16_t * s
, double *i_3
, double *s2_4
, int n
)
530 for (i
= 0; i
< n
; i
++) {
533 x
= s2_4
[0] * s
[i
] + s2_4
[1] * i_3
[0] + s2_4
[2] * i_3
[1] + s2_4
[3] * i_3
[2];
542 schro_iir3_rev_s16_f64 (int16_t * d
, int16_t * s
, double *i_3
, double *s2_4
,
547 for (i
= n
- 1; i
>= 0; i
--) {
550 x
= s2_4
[0] * s
[i
] + s2_4
[1] * i_3
[0] + s2_4
[2] * i_3
[1] + s2_4
[3] * i_3
[2];
559 schro_iir3_across_u8_f64 (uint8_t * d
, uint8_t * s
, double *i1
, double *i2
,
560 double *i3
, double *s2_4
, int n
)
564 for (i
= 0; i
< n
; i
++) {
567 x
= s2_4
[0] * s
[i
] + s2_4
[1] * i1
[i
] + s2_4
[2] * i2
[i
] + s2_4
[3] * i3
[i
];
576 schro_iir3_across_s16_f64 (int16_t * d
, int16_t * s
, double *i1
, double *i2
,
577 double *i3
, double *s2_4
, int n
)
581 for (i
= 0; i
< n
; i
++) {
584 x
= s2_4
[0] * s
[i
] + s2_4
[1] * i1
[i
] + s2_4
[2] * i2
[i
] + s2_4
[3] * i3
[i
];
593 schro_convert_f64_s16 (double *dest
, int16_t * src
, int n
)
596 for (i
= 0; i
< n
; i
++) {
602 schro_iir3_u8_f64 (uint8_t * d
, uint8_t * s
, double *i_3
, double *s2_4
, int n
)
606 for (i
= 0; i
< n
; i
++) {
609 x
= s2_4
[0] * s
[i
] + s2_4
[1] * i_3
[0] + s2_4
[2] * i_3
[1] + s2_4
[3] * i_3
[2];
618 schro_iir3_rev_u8_f64 (uint8_t * d
, uint8_t * s
, double *i_3
, double *s2_4
,
623 for (i
= n
- 1; i
>= 0; i
--) {
626 x
= s2_4
[0] * s
[i
] + s2_4
[1] * i_3
[0] + s2_4
[2] * i_3
[1] + s2_4
[3] * i_3
[2];
635 lowpass2_u8 (uint8_t * d
, uint8_t * s
, double *coeff
, int n
)
642 schro_iir3_u8_f64 (d
, s
, state
, coeff
, n
);
647 schro_iir3_rev_u8_f64 (d
, s
, state
, coeff
, n
);
651 lowpass2_s16 (int16_t * d
, int16_t * s
, double *coeff
, int n
)
658 schro_iir3_s16_f64 (d
, s
, state
, coeff
, n
);
663 schro_iir3_rev_s16_f64 (d
, s
, state
, coeff
, n
);
667 generate_coeff (double *coeff
, double sigma
)
670 double b0
, b0inv
, b1
, b2
, b3
, B
;
673 q
= 0.98711 * sigma
- 0.96330;
675 q
= 3.97156 - 4.41554 * sqrt (1 - 0.26891 * sigma
);
678 b0
= 1.57825 + 2.44413 * q
+ 1.4281 * q
* q
+ 0.422205 * q
* q
* q
;
680 b1
= 2.44413 * q
+ 2.85619 * q
* q
+ 1.26661 * q
* q
* q
;
681 b2
= -1.4281 * q
* q
- 1.26661 * q
* q
* q
;
682 b3
= 0.422205 * q
* q
* q
;
683 B
= 1 - (b1
+ b2
+ b3
) / b0
;
686 coeff
[1] = b1
* b0inv
;
687 coeff
[2] = b2
* b0inv
;
688 coeff
[3] = b3
* b0inv
;
692 schro_frame_component_filter_lowpass2_u8 (SchroFrameData
* comp
,
693 double h_sigma
, double v_sigma
)
698 double *i1
, *i2
, *i3
;
700 generate_coeff (h_coeff
, h_sigma
);
701 generate_coeff (v_coeff
, v_sigma
);
703 i1
= schro_malloc (sizeof (double) * comp
->width
);
704 i2
= schro_malloc (sizeof (double) * comp
->width
);
705 i3
= schro_malloc (sizeof (double) * comp
->width
);
707 for (i
= 0; i
< comp
->height
; i
++) {
708 lowpass2_u8 (OFFSET (comp
->data
, comp
->stride
* i
),
709 OFFSET (comp
->data
, comp
->stride
* i
), h_coeff
, comp
->width
);
712 schro_convert_f64_u8 (i1
, OFFSET (comp
->data
, comp
->stride
* 0), comp
->width
);
713 memcpy (i2
, i1
, sizeof (double) * comp
->width
);
714 memcpy (i3
, i1
, sizeof (double) * comp
->width
);
715 for (i
= 0; i
< comp
->height
; i
++) {
716 schro_iir3_across_u8_f64 (OFFSET (comp
->data
, comp
->stride
* i
),
717 OFFSET (comp
->data
, comp
->stride
* i
),
718 i1
, i2
, i3
, v_coeff
, comp
->width
);
721 schro_convert_f64_u8 (i1
, OFFSET (comp
->data
,
722 comp
->stride
* (comp
->height
- 1)), comp
->width
);
723 memcpy (i2
, i1
, sizeof (double) * comp
->width
);
724 memcpy (i3
, i1
, sizeof (double) * comp
->width
);
725 for (i
= comp
->height
- 1; i
>= 0; i
--) {
726 schro_iir3_across_u8_f64 (OFFSET (comp
->data
, comp
->stride
* i
),
727 OFFSET (comp
->data
, comp
->stride
* i
),
728 i1
, i2
, i3
, v_coeff
, comp
->width
);
737 schro_frame_component_filter_lowpass2_s16 (SchroFrameData
* comp
,
738 double h_sigma
, double v_sigma
)
743 double *i1
, *i2
, *i3
;
745 generate_coeff (h_coeff
, h_sigma
);
746 generate_coeff (v_coeff
, v_sigma
);
748 i1
= schro_malloc (sizeof (double) * comp
->width
);
749 i2
= schro_malloc (sizeof (double) * comp
->width
);
750 i3
= schro_malloc (sizeof (double) * comp
->width
);
752 for (i
= 0; i
< comp
->height
; i
++) {
753 lowpass2_s16 (OFFSET (comp
->data
, comp
->stride
* i
),
754 OFFSET (comp
->data
, comp
->stride
* i
), h_coeff
, comp
->width
);
757 schro_convert_f64_s16 (i1
, OFFSET (comp
->data
, comp
->stride
* 0),
759 memcpy (i2
, i1
, sizeof (double) * comp
->width
);
760 memcpy (i3
, i1
, sizeof (double) * comp
->width
);
761 for (i
= 0; i
< comp
->height
; i
++) {
762 schro_iir3_across_s16_f64 (OFFSET (comp
->data
, comp
->stride
* i
),
763 OFFSET (comp
->data
, comp
->stride
* i
),
764 i1
, i2
, i3
, v_coeff
, comp
->width
);
767 schro_convert_f64_s16 (i1
, OFFSET (comp
->data
,
768 comp
->stride
* (comp
->height
- 1)), comp
->width
);
769 memcpy (i2
, i1
, sizeof (double) * comp
->width
);
770 memcpy (i3
, i1
, sizeof (double) * comp
->width
);
771 for (i
= comp
->height
- 1; i
>= 0; i
--) {
772 schro_iir3_across_s16_f64 (OFFSET (comp
->data
, comp
->stride
* i
),
773 OFFSET (comp
->data
, comp
->stride
* i
),
774 i1
, i2
, i3
, v_coeff
, comp
->width
);
785 schro_frame_filter_lowpass2 (SchroFrame
* frame
, double sigma
)
787 double chroma_sigma_h
;
788 double chroma_sigma_v
;
790 chroma_sigma_h
= sigma
/ (1 << SCHRO_FRAME_FORMAT_H_SHIFT (frame
->format
));
791 chroma_sigma_v
= sigma
/ (1 << SCHRO_FRAME_FORMAT_V_SHIFT (frame
->format
));
793 switch (SCHRO_FRAME_FORMAT_DEPTH (frame
->format
)) {
794 case SCHRO_FRAME_FORMAT_DEPTH_U8
:
795 schro_frame_component_filter_lowpass2_u8 (&frame
->components
[0], sigma
,
797 schro_frame_component_filter_lowpass2_u8 (&frame
->components
[1],
798 chroma_sigma_h
, chroma_sigma_v
);
799 schro_frame_component_filter_lowpass2_u8 (&frame
->components
[2],
800 chroma_sigma_h
, chroma_sigma_v
);
802 case SCHRO_FRAME_FORMAT_DEPTH_S16
:
803 schro_frame_component_filter_lowpass2_s16 (&frame
->components
[0], sigma
,
805 schro_frame_component_filter_lowpass2_s16 (&frame
->components
[1],
806 chroma_sigma_h
, chroma_sigma_v
);
807 schro_frame_component_filter_lowpass2_s16 (&frame
->components
[2],
808 chroma_sigma_h
, chroma_sigma_v
);
819 schro_frame_filter_wavelet (SchroFrame
* frame
)
821 SchroFrame
*tmpframe
;
822 SchroFrameData
*comp
;
829 tmp
= schro_malloc (2 * frame
->width
* sizeof (int16_t));
831 tmpframe
= schro_frame_new_and_alloc (NULL
,
832 SCHRO_FRAME_FORMAT_S16_444
| frame
->format
,
833 ROUND_UP_POW2 (frame
->width
, 5), ROUND_UP_POW2 (frame
->height
, 5));
834 schro_frame_convert (tmpframe
, frame
);
836 params
.transform_depth
= 1;
837 params
.iwt_luma_width
= frame
->width
;
838 params
.iwt_luma_height
= frame
->height
;
839 params
.iwt_chroma_width
= frame
->components
[1].width
;
840 params
.iwt_chroma_height
= frame
->components
[1].height
;
842 for (component
= 0; component
< 3; component
++) {
843 comp
= &tmpframe
->components
[component
];
845 schro_wavelet_transform_2d (comp
, SCHRO_WAVELET_LE_GALL_5_3
, tmp
);
847 for (i
= 1; i
< 4; i
++) {
852 schro_subband_get_frame_data (&fd
, tmpframe
, component
, i
, ¶ms
);
853 schro_histogram_init (&hist
);
855 for (y
= 0; y
< fd
.height
; y
++) {
856 schro_histogram_add_array_s16 (&hist
, OFFSET (fd
.data
, y
* fd
.stride
),
861 for (y
= 0; y
< fd
.height
; y
++) {
862 int16_t *line
= OFFSET (fd
.data
, fd
.stride
* y
);
864 for (x
= 0; x
< fd
.width
; x
++) {
865 if (line
[x
] > -cutoff
&& line
[x
] < cutoff
)
871 schro_wavelet_inverse_transform_2d (comp
, SCHRO_WAVELET_LE_GALL_5_3
, tmp
);
874 schro_frame_convert (frame
, tmpframe
);
875 schro_frame_unref (tmpframe
);
887 x
= -5.0 + rand () * (1.0 / RAND_MAX
) * 10;
888 y
= rand () * (1.0 / RAND_MAX
);
890 if (y
< exp (-x
* x
* 0.5))
896 addnoise_u8 (uint8_t * dest
, int n
, double sigma
)
901 for (i
= 0; i
< n
; i
++) {
902 x
= rint (random_std () * sigma
) + dest
[i
];
903 dest
[i
] = CLAMP (x
, 0, 255);
908 schro_frame_component_filter_addnoise (SchroFrameData
* comp
, double sigma
)
912 for (i
= 0; i
< comp
->height
; i
++) {
913 addnoise_u8 (OFFSET (comp
->data
, comp
->stride
* i
), comp
->width
, sigma
);
918 schro_frame_filter_addnoise (SchroFrame
* frame
, double sigma
)
920 schro_frame_component_filter_addnoise (&frame
->components
[0], sigma
);
921 schro_frame_component_filter_addnoise (&frame
->components
[1], sigma
);
922 schro_frame_component_filter_addnoise (&frame
->components
[2], sigma
);
929 if (i
< (1 << SCHRO_HISTOGRAM_SHIFT
))
931 return 1 << ((i
>> SCHRO_HISTOGRAM_SHIFT
) - 1);
937 if (x
< (1 << SCHRO_HISTOGRAM_SHIFT
))
940 return ((1 << SCHRO_HISTOGRAM_SHIFT
) | (x
& ((1 << SCHRO_HISTOGRAM_SHIFT
) -
941 1))) << ((x
>> SCHRO_HISTOGRAM_SHIFT
) - 1);
946 schro_frame_filter_adaptive_lowpass (SchroFrame
* frame
)
951 int16_t tmpdata
[2048];
956 tmp
= schro_frame_new_and_alloc (NULL
,
957 SCHRO_FRAME_FORMAT_S16_444
| frame
->format
, frame
->width
, frame
->height
);
958 schro_frame_convert (tmp
, frame
);
960 schro_wavelet_transform_2d (&tmp
->components
[0], SCHRO_WAVELET_LE_GALL_5_3
,
963 schro_histogram_init (&hist
);
964 for (j
= 0; j
< tmp
->height
/ 2; j
++) {
965 schro_histogram_add_array_s16 (&hist
,
966 OFFSET (tmp
->components
[0].data
,
967 tmp
->components
[0].stride
* (2 * j
+ 1)), tmp
->width
/ 2);
970 schro_frame_unref (tmp
);
973 slope
= schro_histogram_estimate_slope (&hist
);
975 for (i
= 0; i
< SCHRO_HISTOGRAM_SIZE
; i
++) {
976 schro_dump (SCHRO_DUMP_HIST_TEST
, "%d %g\n",
977 iexpx (i
), hist
.bins
[i
] / ilogx_size (i
));
980 /* good for 2 Mb DVD intra-only rip */
981 sigma
= -1.0 / slope
;
983 SCHRO_DEBUG ("enabling filtering (slope %g)", slope
);
985 schro_frame_filter_lowpass2 (frame
, sigma
);