2 * Copyright (C) 2003 Daniel Moreno <comac@comac.darktech.org>
4 * This file is part of MPlayer.
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * MPlayer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #define PARAM1_DEFAULT 4.0
28 #define PARAM2_DEFAULT 3.0
29 #define PARAM3_DEFAULT 6.0
31 //===========================================================================//
36 unsigned short *Frame
[3];
40 /***************************************************************************/
42 static /*inline*/ unsigned int LowPassMul(unsigned int PrevMul
, unsigned int CurrMul
, int* Coef
){
43 // int dMul= (PrevMul&0xFFFFFF)-(CurrMul&0xFFFFFF);
44 int dMul
= PrevMul
-CurrMul
;
45 unsigned int d
=((dMul
+0x10007FF)>>12);
46 return CurrMul
+ Coef
[d
];
49 static void deNoiseTemporal(
50 unsigned char *Frame
, // mpi->planes[x]
51 unsigned char *FrameDest
, // dmpi->planes[x]
52 unsigned short *FrameAnt
,
53 int W
, int H
, int sStride
, int dStride
,
57 unsigned int PixelDst
;
59 for (Y
= 0; Y
< H
; Y
++){
60 for (X
= 0; X
< W
; X
++){
61 PixelDst
= LowPassMul(FrameAnt
[X
]<<8, Frame
[X
]<<16, Temporal
);
62 FrameAnt
[X
] = ((PixelDst
+0x1000007F)>>8);
63 FrameDest
[X
]= ((PixelDst
+0x10007FFF)>>16);
71 static void deNoiseSpacial(
72 unsigned char *Frame
, // mpi->planes[x]
73 unsigned char *FrameDest
, // dmpi->planes[x]
74 unsigned int *LineAnt
, // vf->priv->Line (width bytes)
75 int W
, int H
, int sStride
, int dStride
,
76 int *Horizontal
, int *Vertical
)
79 long sLineOffs
= 0, dLineOffs
= 0;
80 unsigned int PixelAnt
;
81 unsigned int PixelDst
;
83 /* First pixel has no left nor top neighbor. */
84 PixelDst
= LineAnt
[0] = PixelAnt
= Frame
[0]<<16;
85 FrameDest
[0]= ((PixelDst
+0x10007FFF)>>16);
87 /* First line has no top neighbor, only left. */
88 for (X
= 1; X
< W
; X
++){
89 PixelDst
= LineAnt
[X
] = LowPassMul(PixelAnt
, Frame
[X
]<<16, Horizontal
);
90 FrameDest
[X
]= ((PixelDst
+0x10007FFF)>>16);
93 for (Y
= 1; Y
< H
; Y
++){
94 unsigned int PixelAnt
;
95 sLineOffs
+= sStride
, dLineOffs
+= dStride
;
96 /* First pixel on each line doesn't have previous pixel */
97 PixelAnt
= Frame
[sLineOffs
]<<16;
98 PixelDst
= LineAnt
[0] = LowPassMul(LineAnt
[0], PixelAnt
, Vertical
);
99 FrameDest
[dLineOffs
]= ((PixelDst
+0x10007FFF)>>16);
101 for (X
= 1; X
< W
; X
++){
102 unsigned int PixelDst
;
103 /* The rest are normal */
104 PixelAnt
= LowPassMul(PixelAnt
, Frame
[sLineOffs
+X
]<<16, Horizontal
);
105 PixelDst
= LineAnt
[X
] = LowPassMul(LineAnt
[X
], PixelAnt
, Vertical
);
106 FrameDest
[dLineOffs
+X
]= ((PixelDst
+0x10007FFF)>>16);
111 static void deNoise(unsigned char *Frame
, // mpi->planes[x]
112 unsigned char *FrameDest
, // dmpi->planes[x]
113 unsigned int *LineAnt
, // vf->priv->Line (width bytes)
114 unsigned short **FrameAntPtr
,
115 int W
, int H
, int sStride
, int dStride
,
116 int *Horizontal
, int *Vertical
, int *Temporal
)
119 long sLineOffs
= 0, dLineOffs
= 0;
120 unsigned int PixelAnt
;
121 unsigned int PixelDst
;
122 unsigned short* FrameAnt
=(*FrameAntPtr
);
125 (*FrameAntPtr
)=FrameAnt
=malloc(W
*H
*sizeof(unsigned short));
126 for (Y
= 0; Y
< H
; Y
++){
127 unsigned short* dst
=&FrameAnt
[Y
*W
];
128 unsigned char* src
=Frame
+Y
*sStride
;
129 for (X
= 0; X
< W
; X
++) dst
[X
]=src
[X
]<<8;
133 if(!Horizontal
[0] && !Vertical
[0]){
134 deNoiseTemporal(Frame
, FrameDest
, FrameAnt
,
135 W
, H
, sStride
, dStride
, Temporal
);
139 deNoiseSpacial(Frame
, FrameDest
, LineAnt
,
140 W
, H
, sStride
, dStride
, Horizontal
, Vertical
);
144 /* First pixel has no left nor top neighbor. Only previous frame */
145 LineAnt
[0] = PixelAnt
= Frame
[0]<<16;
146 PixelDst
= LowPassMul(FrameAnt
[0]<<8, PixelAnt
, Temporal
);
147 FrameAnt
[0] = ((PixelDst
+0x1000007F)>>8);
148 FrameDest
[0]= ((PixelDst
+0x10007FFF)>>16);
150 /* First line has no top neighbor. Only left one for each pixel and
152 for (X
= 1; X
< W
; X
++){
153 LineAnt
[X
] = PixelAnt
= LowPassMul(PixelAnt
, Frame
[X
]<<16, Horizontal
);
154 PixelDst
= LowPassMul(FrameAnt
[X
]<<8, PixelAnt
, Temporal
);
155 FrameAnt
[X
] = ((PixelDst
+0x1000007F)>>8);
156 FrameDest
[X
]= ((PixelDst
+0x10007FFF)>>16);
159 for (Y
= 1; Y
< H
; Y
++){
160 unsigned int PixelAnt
;
161 unsigned short* LinePrev
=&FrameAnt
[Y
*W
];
162 sLineOffs
+= sStride
, dLineOffs
+= dStride
;
163 /* First pixel on each line doesn't have previous pixel */
164 PixelAnt
= Frame
[sLineOffs
]<<16;
165 LineAnt
[0] = LowPassMul(LineAnt
[0], PixelAnt
, Vertical
);
166 PixelDst
= LowPassMul(LinePrev
[0]<<8, LineAnt
[0], Temporal
);
167 LinePrev
[0] = ((PixelDst
+0x1000007F)>>8);
168 FrameDest
[dLineOffs
]= ((PixelDst
+0x10007FFF)>>16);
170 for (X
= 1; X
< W
; X
++){
171 unsigned int PixelDst
;
172 /* The rest are normal */
173 PixelAnt
= LowPassMul(PixelAnt
, Frame
[sLineOffs
+X
]<<16, Horizontal
);
174 LineAnt
[X
] = LowPassMul(LineAnt
[X
], PixelAnt
, Vertical
);
175 PixelDst
= LowPassMul(LinePrev
[X
]<<8, LineAnt
[X
], Temporal
);
176 LinePrev
[X
] = ((PixelDst
+0x1000007F)>>8);
177 FrameDest
[dLineOffs
+X
]= ((PixelDst
+0x10007FFF)>>16);
183 //===========================================================================//
185 static void PrecalcCoefs(int *Ct
, double Dist25
)
188 double Gamma
, Simil
, C
;
190 Gamma
= log(0.25) / log(1.0 - Dist25
/255.0 - 0.00001);
192 for (i
= -255*16; i
<= 255*16; i
++)
194 Simil
= 1.0 - abs(i
) / (16*255.0);
195 C
= pow(Simil
, Gamma
) * 65536.0 * (double)i
/ 16.0;
196 Ct
[16*256+i
] = (C
<0) ? (C
-0.5) : (C
+0.5);
199 Ct
[0] = (Dist25
!= 0);
203 //===========================================================================//