comparison libmpcodecs/vf_delogo.c @ 10809:304c94c89359

simple logo remover
author henry
date Wed, 03 Sep 2003 22:44:28 +0000
parents
children a69221e84948
comparison
equal deleted inserted replaced
10808:9883dfced49c 10809:304c94c89359
1 /*
2 Copyright (C) 2002 Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
3
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.
8
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.
13
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 /* A very simple tv station logo remover */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <inttypes.h>
25 #include <math.h>
26
27 #include "../config.h"
28 #include "../mp_msg.h"
29 #include "../cpudetect.h"
30
31 #ifdef HAVE_MALLOC_H
32 #include <malloc.h>
33 #endif
34
35 #include "img_format.h"
36 #include "mp_image.h"
37 #include "vf.h"
38 #include "../libvo/fastmemcpy.h"
39
40 //===========================================================================//
41
42 struct vf_priv_s {
43 unsigned int outfmt;
44 int xoff, yoff, lw, lh, band, show;
45 };
46
47 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
48 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
49
50 static void delogo(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int width, int height,
51 int logo_x, int logo_y, int logo_w, int logo_h, int band, int show) {
52 int y, x;
53 int interp, dist;
54 uint8_t *xdst, *xsrc;
55
56 uint8_t *topleft, *botleft, *topright;
57 int xclipl, xclipr, yclipt, yclipb;
58
59 xclipl = MAX(-logo_x, 0);
60 xclipr = MAX(logo_x+logo_w-width, 0);
61 yclipt = MAX(-logo_y, 0);
62 yclipb = MAX(logo_y+logo_h-height, 0);
63
64 topleft = src+MAX(logo_y,0)*srcStride+MAX(logo_x,0);
65 topright = src+MAX(logo_y,0)*srcStride+MIN(logo_x+logo_w-1,width-1);
66 botleft = src+MIN(logo_y+logo_h-1,height-1)*srcStride+MAX(logo_x,0);
67
68 for(y=0; y<height; y++)
69 {
70 for (x = 0, xdst = dst, xsrc = src; x < width; x++, xdst++, xsrc++) {
71 if (y >= logo_y && y < logo_y+logo_h && x >= logo_x && x < logo_x+logo_w) {
72 interp = ((topleft[srcStride*(y-logo_y-yclipt)]
73 + topleft[srcStride*(y-logo_y-1-yclipt)]
74 + topleft[srcStride*(y-logo_y+1-yclipt)])*(logo_w-(x-logo_x))/logo_w
75 + (topright[srcStride*(y-logo_y-yclipt)]
76 + topright[srcStride*(y-logo_y-1-yclipt)]
77 + topright[srcStride*(y-logo_y+1-yclipt)])*(x-logo_x)/logo_w
78 + (topleft[x-logo_x-xclipl]
79 + topleft[x-logo_x-1-xclipl]
80 + topleft[x-logo_x+1-xclipl])*(logo_h-(y-logo_y))/logo_h
81 + (botleft[x-logo_x-xclipl]
82 + botleft[x-logo_x-1-xclipl]
83 + botleft[x-logo_x+1-xclipl])*(y-logo_y)/logo_h
84 )/6;
85 /* interp = (topleft[srcStride*(y-logo_y)]*(logo_w-(x-logo_x))/logo_w
86 + topright[srcStride*(y-logo_y)]*(x-logo_x)/logo_w
87 + topleft[x-logo_x]*(logo_h-(y-logo_y))/logo_h
88 + botleft[x-logo_x]*(y-logo_y)/logo_h
89 )/2;*/
90 if (y >= logo_y+band && y < logo_y+logo_h-band && x >= logo_x+band && x < logo_x+logo_w-band) {
91 *xdst = interp;
92 } else {
93 dist = 0;
94 if (x < logo_x+band) dist = MAX(dist, logo_x-x+band);
95 else if (x >= logo_x+logo_w-band) dist = MAX(dist, x-(logo_x+logo_w-1-band));
96 if (y < logo_y+band) dist = MAX(dist, logo_y-y+band);
97 else if (y >= logo_y+logo_h-band) dist = MAX(dist, y-(logo_y+logo_h-1-band));
98 *xdst = (*xsrc*dist + interp*(band-dist))/band;
99 if (show && dist == band) *xdst = 0;
100 }
101 } else {
102 *xdst = *xsrc;
103 }
104 }
105
106 dst+= dstStride;
107 src+= srcStride;
108 }
109 }
110
111 static int config(struct vf_instance_s* vf,
112 int width, int height, int d_width, int d_height,
113 unsigned int flags, unsigned int outfmt){
114
115 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
116 }
117
118
119 static void get_image(struct vf_instance_s* vf, mp_image_t *mpi){
120 if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change
121 if(mpi->imgfmt!=vf->priv->outfmt) return; // colorspace differ
122 // ok, we can do pp in-place (or pp disabled):
123 vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
124 mpi->type, mpi->flags, mpi->w, mpi->h);
125 mpi->planes[0]=vf->dmpi->planes[0];
126 mpi->stride[0]=vf->dmpi->stride[0];
127 mpi->width=vf->dmpi->width;
128 if(mpi->flags&MP_IMGFLAG_PLANAR){
129 mpi->planes[1]=vf->dmpi->planes[1];
130 mpi->planes[2]=vf->dmpi->planes[2];
131 mpi->stride[1]=vf->dmpi->stride[1];
132 mpi->stride[2]=vf->dmpi->stride[2];
133 }
134 mpi->flags|=MP_IMGFLAG_DIRECT;
135 }
136
137 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
138 mp_image_t *dmpi;
139
140 if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
141 // no DR, so get a new image! hope we'll get DR buffer:
142 vf->dmpi=vf_get_image(vf->next,vf->priv->outfmt,
143 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
144 mpi->w,mpi->h);
145 }
146 dmpi= vf->dmpi;
147
148 delogo(dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h,
149 vf->priv->xoff, vf->priv->yoff, vf->priv->lw, vf->priv->lh, vf->priv->band, vf->priv->show);
150 delogo(dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w/2, mpi->h/2,
151 vf->priv->xoff/2, vf->priv->yoff/2, vf->priv->lw/2, vf->priv->lh/2, vf->priv->band/2, vf->priv->show);
152 delogo(dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w/2, mpi->h/2,
153 vf->priv->xoff/2, vf->priv->yoff/2, vf->priv->lw/2, vf->priv->lh/2, vf->priv->band/2, vf->priv->show);
154
155 vf_clone_mpi_attributes(dmpi, mpi);
156
157 return vf_next_put_image(vf,dmpi);
158 }
159
160 static void uninit(struct vf_instance_s* vf){
161 if(!vf->priv) return;
162
163 free(vf->priv);
164 vf->priv=NULL;
165 }
166
167 //===========================================================================//
168
169 static int query_format(struct vf_instance_s* vf, unsigned int fmt){
170 switch(fmt)
171 {
172 case IMGFMT_YV12:
173 case IMGFMT_I420:
174 case IMGFMT_IYUV:
175 return vf_next_query_format(vf,vf->priv->outfmt);
176 }
177 return 0;
178 }
179
180 static unsigned int fmt_list[]={
181 IMGFMT_YV12,
182 IMGFMT_I420,
183 IMGFMT_IYUV,
184 0
185 };
186
187 static int open(vf_instance_t *vf, char* args){
188 int res;
189
190 vf->config=config;
191 vf->put_image=put_image;
192 vf->get_image=get_image;
193 vf->query_format=query_format;
194 vf->uninit=uninit;
195 vf->priv=malloc(sizeof(struct vf_priv_s));
196 memset(vf->priv, 0, sizeof(struct vf_priv_s));
197
198 if (args) res = sscanf(args, "%d:%d:%d:%d:%d",
199 &vf->priv->xoff, &vf->priv->yoff,
200 &vf->priv->lw, &vf->priv->lh,
201 &vf->priv->band);
202
203 if (res != 5) {
204 mp_msg(MSGT_VFILTER, MSGL_ERR, "deLogo: syntax is \"delogo=xoff:yoff:width:height:band\"\n");
205 uninit(vf);
206 return 0;
207 }
208
209 mp_msg(MSGT_VFILTER, MSGL_INFO, "deLogo: %d x %d, %d ; %d ; band = %d\n",
210 &vf->priv->lw, &vf->priv->lh,
211 &vf->priv->xoff, &vf->priv->yoff,
212 &vf->priv->band);
213
214 vf->priv->show = 0;
215
216 if (vf->priv->band < 0) {
217 vf->priv->band = 2;
218 vf->priv->show = 1;
219 }
220
221
222 vf->priv->lw += vf->priv->band*2;
223 vf->priv->lh += vf->priv->band*2;
224 vf->priv->xoff -= vf->priv->band;
225 vf->priv->yoff -= vf->priv->band;
226
227 // check csp:
228 vf->priv->outfmt=vf_match_csp(&vf->next,fmt_list,IMGFMT_YV12);
229 if(!vf->priv->outfmt)
230 {
231 uninit(vf);
232 return 0; // no csp match :(
233 }
234
235 return 1;
236 }
237
238 vf_info_t vf_info_delogo = {
239 "simple logo remover",
240 "delogo",
241 "Jindrich Makovicka",
242 "",
243 open,
244 NULL
245 };
246
247 //===========================================================================//