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"
35 #include "libvo/fastmemcpy.h"
38 //===========================================================================//
40 typedef struct FilterParam
{
46 FilterParam lumaParam
;
47 FilterParam chromaParam
;
51 /***************************************************************************/
54 static int config(struct vf_instance_s
* vf
,
55 int width
, int height
, int d_width
, int d_height
,
56 unsigned int flags
, unsigned int outfmt
){
58 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
61 static inline void blur(uint8_t *dst
, uint8_t *src
, int w
, int radius
, int dstStep
, int srcStep
){
63 const int length
= radius
*2 + 1;
64 const int inv
= ((1<<16) + length
/2)/length
;
68 for(x
=0; x
<radius
; x
++){
69 sum
+= src
[x
*srcStep
]<<1;
71 sum
+= src
[radius
*srcStep
];
73 for(x
=0; x
<=radius
; x
++){
74 sum
+= src
[(radius
+x
)*srcStep
] - src
[(radius
-x
)*srcStep
];
75 dst
[x
*dstStep
]= (sum
*inv
+ (1<<15))>>16;
78 for(; x
<w
-radius
; x
++){
79 sum
+= src
[(radius
+x
)*srcStep
] - src
[(x
-radius
-1)*srcStep
];
80 dst
[x
*dstStep
]= (sum
*inv
+ (1<<15))>>16;
84 sum
+= src
[(2*w
-radius
-x
-1)*srcStep
] - src
[(x
-radius
-1)*srcStep
];
85 dst
[x
*dstStep
]= (sum
*inv
+ (1<<15))>>16;
89 static inline void blur2(uint8_t *dst
, uint8_t *src
, int w
, int radius
, int power
, int dstStep
, int srcStep
){
90 uint8_t temp
[2][4096];
91 uint8_t *a
= temp
[0], *b
=temp
[1];
94 blur(a
, src
, w
, radius
, 1, srcStep
);
95 for(; power
>2; power
--){
97 blur(b
, a
, w
, radius
, 1, 1);
101 blur(dst
, a
, w
, radius
, dstStep
, 1);
105 dst
[i
*dstStep
]= a
[i
];
110 dst
[i
*dstStep
]= src
[i
*srcStep
];
114 static void hBlur(uint8_t *dst
, uint8_t *src
, int w
, int h
, int dstStride
, int srcStride
, int radius
, int power
){
117 if(radius
==0 && dst
==src
) return;
120 blur2(dst
+ y
*dstStride
, src
+ y
*srcStride
, w
, radius
, power
, 1, 1);
124 //FIXME optimize (x before y !!!)
125 static void vBlur(uint8_t *dst
, uint8_t *src
, int w
, int h
, int dstStride
, int srcStride
, int radius
, int power
){
128 if(radius
==0 && dst
==src
) return;
131 blur2(dst
+ x
, src
+ x
, h
, radius
, power
, dstStride
, srcStride
);
135 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
136 int cw
= mpi
->w
>> mpi
->chroma_x_shift
;
137 int ch
= mpi
->h
>> mpi
->chroma_y_shift
;
139 mp_image_t
*dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
140 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
| MP_IMGFLAG_READABLE
,
143 assert(mpi
->flags
&MP_IMGFLAG_PLANAR
);
145 hBlur(dmpi
->planes
[0], mpi
->planes
[0], mpi
->w
,mpi
->h
,
146 dmpi
->stride
[0], mpi
->stride
[0], vf
->priv
->lumaParam
.radius
, vf
->priv
->lumaParam
.power
);
147 hBlur(dmpi
->planes
[1], mpi
->planes
[1], cw
,ch
,
148 dmpi
->stride
[1], mpi
->stride
[1], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
149 hBlur(dmpi
->planes
[2], mpi
->planes
[2], cw
,ch
,
150 dmpi
->stride
[2], mpi
->stride
[2], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
152 vBlur(dmpi
->planes
[0], dmpi
->planes
[0], mpi
->w
,mpi
->h
,
153 dmpi
->stride
[0], dmpi
->stride
[0], vf
->priv
->lumaParam
.radius
, vf
->priv
->lumaParam
.power
);
154 vBlur(dmpi
->planes
[1], dmpi
->planes
[1], cw
,ch
,
155 dmpi
->stride
[1], dmpi
->stride
[1], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
156 vBlur(dmpi
->planes
[2], dmpi
->planes
[2], cw
,ch
,
157 dmpi
->stride
[2], dmpi
->stride
[2], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
159 return vf_next_put_image(vf
,dmpi
, pts
);
162 //===========================================================================//
164 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
174 return vf_next_query_format(vf
, fmt
);
179 static int open(vf_instance_t
*vf
, char* args
){
183 vf
->put_image
=put_image
;
184 // vf->get_image=get_image;
185 vf
->query_format
=query_format
;
186 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
187 memset(vf
->priv
, 0, sizeof(struct vf_priv_s
));
189 if(args
==NULL
) return 0;
191 e
=sscanf(args
, "%d:%d:%d:%d",
192 &vf
->priv
->lumaParam
.radius
,
193 &vf
->priv
->lumaParam
.power
,
194 &vf
->priv
->chromaParam
.radius
,
195 &vf
->priv
->chromaParam
.power
199 vf
->priv
->chromaParam
.radius
= vf
->priv
->lumaParam
.radius
;
200 vf
->priv
->chromaParam
.power
= vf
->priv
->lumaParam
.power
;
204 if(vf
->priv
->lumaParam
.radius
< 0) return 0;
205 if(vf
->priv
->chromaParam
.radius
< 0) return 0;
210 vf_info_t vf_info_boxblur
= {
213 "Michael Niedermayer",
219 //===========================================================================//