2 Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32 #include "img_format.h"
37 //===========================================================================//
39 typedef struct FilterParam
{
45 FilterParam lumaParam
;
46 FilterParam chromaParam
;
50 /***************************************************************************/
53 static int config(struct vf_instance_s
* vf
,
54 int width
, int height
, int d_width
, int d_height
,
55 unsigned int flags
, unsigned int outfmt
){
57 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
60 static inline void blur(uint8_t *dst
, uint8_t *src
, int w
, int radius
, int dstStep
, int srcStep
){
62 const int length
= radius
*2 + 1;
63 const int inv
= ((1<<16) + length
/2)/length
;
67 for(x
=0; x
<radius
; x
++){
68 sum
+= src
[x
*srcStep
]<<1;
70 sum
+= src
[radius
*srcStep
];
72 for(x
=0; x
<=radius
; x
++){
73 sum
+= src
[(radius
+x
)*srcStep
] - src
[(radius
-x
)*srcStep
];
74 dst
[x
*dstStep
]= (sum
*inv
+ (1<<15))>>16;
77 for(; x
<w
-radius
; x
++){
78 sum
+= src
[(radius
+x
)*srcStep
] - src
[(x
-radius
-1)*srcStep
];
79 dst
[x
*dstStep
]= (sum
*inv
+ (1<<15))>>16;
83 sum
+= src
[(2*w
-radius
-x
-1)*srcStep
] - src
[(x
-radius
-1)*srcStep
];
84 dst
[x
*dstStep
]= (sum
*inv
+ (1<<15))>>16;
88 static inline void blur2(uint8_t *dst
, uint8_t *src
, int w
, int radius
, int power
, int dstStep
, int srcStep
){
89 uint8_t temp
[2][4096];
90 uint8_t *a
= temp
[0], *b
=temp
[1];
93 blur(a
, src
, w
, radius
, 1, srcStep
);
94 for(; power
>2; power
--){
96 blur(b
, a
, w
, radius
, 1, 1);
100 blur(dst
, a
, w
, radius
, dstStep
, 1);
104 dst
[i
*dstStep
]= a
[i
];
109 dst
[i
*dstStep
]= src
[i
*srcStep
];
113 static void hBlur(uint8_t *dst
, uint8_t *src
, int w
, int h
, int dstStride
, int srcStride
, int radius
, int power
){
116 if(radius
==0 && dst
==src
) return;
119 blur2(dst
+ y
*dstStride
, src
+ y
*srcStride
, w
, radius
, power
, 1, 1);
123 //FIXME optimize (x before y !!!)
124 static void vBlur(uint8_t *dst
, uint8_t *src
, int w
, int h
, int dstStride
, int srcStride
, int radius
, int power
){
127 if(radius
==0 && dst
==src
) return;
130 blur2(dst
+ x
, src
+ x
, h
, radius
, power
, dstStride
, srcStride
);
134 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
135 int cw
= mpi
->w
>> mpi
->chroma_x_shift
;
136 int ch
= mpi
->h
>> mpi
->chroma_y_shift
;
138 mp_image_t
*dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
139 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
| MP_IMGFLAG_READABLE
,
142 assert(mpi
->flags
&MP_IMGFLAG_PLANAR
);
144 hBlur(dmpi
->planes
[0], mpi
->planes
[0], mpi
->w
,mpi
->h
,
145 dmpi
->stride
[0], mpi
->stride
[0], vf
->priv
->lumaParam
.radius
, vf
->priv
->lumaParam
.power
);
146 hBlur(dmpi
->planes
[1], mpi
->planes
[1], cw
,ch
,
147 dmpi
->stride
[1], mpi
->stride
[1], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
148 hBlur(dmpi
->planes
[2], mpi
->planes
[2], cw
,ch
,
149 dmpi
->stride
[2], mpi
->stride
[2], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
151 vBlur(dmpi
->planes
[0], dmpi
->planes
[0], mpi
->w
,mpi
->h
,
152 dmpi
->stride
[0], dmpi
->stride
[0], vf
->priv
->lumaParam
.radius
, vf
->priv
->lumaParam
.power
);
153 vBlur(dmpi
->planes
[1], dmpi
->planes
[1], cw
,ch
,
154 dmpi
->stride
[1], dmpi
->stride
[1], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
155 vBlur(dmpi
->planes
[2], dmpi
->planes
[2], cw
,ch
,
156 dmpi
->stride
[2], dmpi
->stride
[2], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
158 return vf_next_put_image(vf
,dmpi
, pts
);
161 //===========================================================================//
163 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
173 return vf_next_query_format(vf
, fmt
);
178 static int open(vf_instance_t
*vf
, char* args
){
182 vf
->put_image
=put_image
;
183 // vf->get_image=get_image;
184 vf
->query_format
=query_format
;
185 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
186 memset(vf
->priv
, 0, sizeof(struct vf_priv_s
));
188 if(args
==NULL
) return 0;
190 e
=sscanf(args
, "%d:%d:%d:%d",
191 &vf
->priv
->lumaParam
.radius
,
192 &vf
->priv
->lumaParam
.power
,
193 &vf
->priv
->chromaParam
.radius
,
194 &vf
->priv
->chromaParam
.power
198 vf
->priv
->chromaParam
.radius
= vf
->priv
->lumaParam
.radius
;
199 vf
->priv
->chromaParam
.power
= vf
->priv
->lumaParam
.power
;
203 if(vf
->priv
->lumaParam
.radius
< 0) return 0;
204 if(vf
->priv
->chromaParam
.radius
< 0) return 0;
209 const vf_info_t vf_info_boxblur
= {
212 "Michael Niedermayer",
218 //===========================================================================//