1 /***************************************************************************
2 ADM_vidClean.cpp - description
3 -------------------
4 begin : Sun Apr 14 2002
5 copyright : (C) 2002 by mean
6 email : fixounet@free.fr
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17 #include "ADM_default.h"
18
19
20 #include "ADM_editor/ADM_edit.hxx"
21 #include "ADM_videoFilter.h"
22 #include "ADM_video/ADM_vidClean.h"
23
24
25
26 static FILTER_PARAM smoothParam={2,{"radius","blend"}};
27
28
29 SCRIPT_CREATE(smooth_script,AVDMVideoSmooth,smoothParam);
30
printConf(void)31 char *AVDMVideoSmooth::printConf(void)
32 {
33 static char str[40];
34 sprintf(str,"Smooth-Clean : R = %02lu, Blend=%01lu",_param->radius*2,_param->blend);
35 return str; // this one is pure
36 }
37 BUILD_CREATE(smooth_create,AVDMVideoSmooth);
38
39 //_______________________________________________________________
40
AVDMVideoSmooth(AVDMGenericVideoStream * in,CONFcouple * couples)41 AVDMVideoSmooth::AVDMVideoSmooth(
42 AVDMGenericVideoStream *in,CONFcouple *couples)
43 {
44
45
46 _in=in;
47 memcpy(&_info,_in->getInfo(),sizeof(_info));
48 if(couples)
49 {
50 _param=NEW( SMOOTH_PARAMS);
51 GET(radius);
52 GET(blend);
53 }
54 else
55 {
56 _param=NEW( SMOOTH_PARAMS);
57 _param->radius=3;
58 _param->blend=1;
59 }
60
61
62
63 _uncompressed=new ADMImage (_in->getInfo()->width,_in->getInfo()->height);
64 ADM_assert(_uncompressed);
65 _info.encoding=1;
66
67
68 }
69
getCoupledConf(CONFcouple ** couples)70 uint8_t AVDMVideoSmooth::getCoupledConf( CONFcouple **couples)
71 {
72
73 ADM_assert(_param);
74 *couples=new CONFcouple(2);
75
76 CSET(radius);
77 CSET(blend);
78 return 1;
79
80 }
~AVDMVideoSmooth()81 AVDMVideoSmooth::~AVDMVideoSmooth()
82 {
83 delete _uncompressed;
84 DELETE(_param);
85 _uncompressed=NULL;
86 }
87
getFrameNumberNoAlloc(uint32_t frame,uint32_t * len,ADMImage * data,uint32_t * flags)88 uint8_t AVDMVideoSmooth::getFrameNumberNoAlloc(uint32_t frame,
89 uint32_t *len,
90 ADMImage *data,
91 uint32_t *flags)
92 {
93 uint8_t *dst,*dstu,*dstv,*src,*srcu,*srcv;
94
95 int16_t l,u=0,v=0;
96 int16_t nb;
97 int16_t fl,fu,fv;
98 int16_t ldelta,udelta,vdelta;
99 int16_t threshold=10,su=0,sv=0;
100
101 if(frame>=_info.nb_frames) return 0;
102 ADM_assert(_uncompressed);
103
104 // read uncompressed frame
105 if(!_in->getFrameNumberNoAlloc(frame, len,_uncompressed,flags)) return 0;
106
107 src=YPLANE(_uncompressed);
108 srcu=UPLANE(_uncompressed);;
109 srcv=VPLANE(_uncompressed);;
110
111 dst=YPLANE(data);
112 dstu=UPLANE(data);
113 dstv=VPLANE(data);
114
115 int16_t radius=_param->radius;
116
117 for(int32_t y=0;y<(int32_t)(_info.height );y++)
118 {
119 for(int32_t x=0;x<(int32_t)(_info.width );x++)
120 {
121 // for each pixel we take the surrounding one
122 // if threshold is not met
123 l=getPixel(x,y,_uncompressed->data);
124 if(!(x&1))
125 {
126 u=getPixelU(x,y,srcu);
127 v=getPixelU(x,y,srcv);
128 }
129 nb=0;
130 fl=0;fu=0;fv=0;
131
132
133 //------------------------
134 for(int16_t yy=-radius+1;yy<radius;yy++)
135 {
136
137 for(int16_t xx=-radius+1;xx<radius;xx++)
138 {
139 if( (xx*xx+yy*yy)<radius*radius)
140 {
141 ldelta =getPixel(x+xx,y+yy,_uncompressed->data)-l;
142 udelta=getPixelU(x+xx,y+yy,srcu)-u;
143 vdelta=getPixelU(x+xx,y+yy,srcv)-v;
144
145
146 if((udelta*udelta<threshold*threshold)&&
147 (vdelta*vdelta<threshold*threshold) &&
148 (ldelta*ldelta<threshold*threshold))
149 {
150 nb++;
151 fl=fl+ldelta+l;
152 fu=fu+udelta+u;
153 fv=fv+vdelta+v;
154 }
155 }
156 }
157 }
158 //----------------------------------
159 //
160 // average value
161 fl=fl/nb;
162 fu=fu/nb;
163 fv=fv/nb;
164 // now melt it
165 // 50/50
166 /* fl=(fl+l)>>1;
167 fu=(fu+u)>>1;
168 fv=(fv+v)>>1;*/
169
170 *dst++=fl;
171 if(y&1)
172 if(x&1)
173 {
174 setPixelU( (su+fu)>>1,x,y,dstu);
175 setPixelU( (sv+fv)>>1,x,y,dstv);
176 }
177 else
178 {
179 su=fu;
180 sv=fv;
181 }
182
183 } // end for x
184
185 } // end for y
186 data->copyInfo(_uncompressed);
187 return 1;
188 }
configure(AVDMGenericVideoStream * instream)189 uint8_t AVDMVideoSmooth::configure( AVDMGenericVideoStream *instream)
190 {
191 UNUSED_ARG(instream);
192
193 SMOOTH_PARAMS *par;
194
195 // par=_param;
196 //return((uint8_t)getSmoothParams(&par->radius,&par->blend));
197 return 1;
198 //#warning FIXME , CODE REMOVED AMD64/GCC4
199 }
200