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