Parent Directory
|
Revision Log
Revision 1.1.2.3 - (view) (download)
1 : | suxen_drol | 1.1.2.1 | /***************************************************************************** |
2 : | * | ||
3 : | * XVID MPEG-4 VIDEO CODEC | ||
4 : | * Reduced-Resolution utilities | ||
5 : | * | ||
6 : | * Copyright(C) 2002 Pascal Massimino <skal@planet-d.net> | ||
7 : | * | ||
8 : | * This file is part of XviD, a free MPEG-4 video encoder/decoder | ||
9 : | * | ||
10 : | * XviD is free software; you can redistribute it and/or modify it | ||
11 : | * under the terms of the GNU General Public License as published by | ||
12 : | * the Free Software Foundation; either version 2 of the License, or | ||
13 : | * (at your option) any later version. | ||
14 : | * | ||
15 : | * This program is distributed in the hope that it will be useful, | ||
16 : | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 : | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 : | * GNU General Public License for more details. | ||
19 : | * | ||
20 : | * You should have received a copy of the GNU General Public License | ||
21 : | * along with this program; if not, write to the Free Software | ||
22 : | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 : | * | ||
24 : | * Under section 8 of the GNU General Public License, the copyright | ||
25 : | * holders of XVID explicitly forbid distribution in the following | ||
26 : | * countries: | ||
27 : | * | ||
28 : | * - Japan | ||
29 : | * - United States of America | ||
30 : | * | ||
31 : | * Linking XviD statically or dynamically with other modules is making a | ||
32 : | * combined work based on XviD. Thus, the terms and conditions of the | ||
33 : | * GNU General Public License cover the whole combination. | ||
34 : | * | ||
35 : | * As a special exception, the copyright holders of XviD give you | ||
36 : | * permission to link XviD with independent modules that communicate with | ||
37 : | * XviD solely through the VFW1.1 and DShow interfaces, regardless of the | ||
38 : | * license terms of these independent modules, and to copy and distribute | ||
39 : | * the resulting combined work under terms of your choice, provided that | ||
40 : | * every copy of the combined work is accompanied by a complete copy of | ||
41 : | * the source code of XviD (the version of XviD used to produce the | ||
42 : | * combined work), being distributed under the terms of the GNU General | ||
43 : | * Public License plus this exception. An independent module is a module | ||
44 : | * which is not derived from or based on XviD. | ||
45 : | * | ||
46 : | * Note that people who make modified versions of XviD are not obligated | ||
47 : | * to grant this special exception for their modified versions; it is | ||
48 : | * their choice whether to do so. The GNU General Public License gives | ||
49 : | * permission to release a modified version without this exception; this | ||
50 : | * exception also makes it possible to release a modified version which | ||
51 : | * carries forward this exception. | ||
52 : | * | ||
53 : | suxen_drol | 1.1.2.3 | * $Id: reduced.c,v 1.1.2.2 2002/12/09 10:47:05 suxen_drol Exp $ |
54 : | suxen_drol | 1.1.2.1 | * |
55 : | ****************************************************************************/ | ||
56 : | |||
57 : | #include "../portab.h" | ||
58 : | suxen_drol | 1.1.2.3 | #include "../global.h" |
59 : | suxen_drol | 1.1.2.1 | #include "reduced.h" |
60 : | |||
61 : | // function pointers | ||
62 : | COPY_UPSAMPLED_8X8_16TO8 * copy_upsampled_8x8_16to8; | ||
63 : | ADD_UPSAMPLED_8X8_16TO8 * add_upsampled_8x8_16to8; | ||
64 : | VFILTER_31 * vfilter_31; | ||
65 : | HFILTER_31 * hfilter_31; | ||
66 : | suxen_drol | 1.1.2.2 | FILTER_18X18_TO_8X8 * filter_18x18_to_8x8; |
67 : | FILTER_DIFF_18X18_TO_8X8 * filter_diff_18x18_to_8x8; | ||
68 : | suxen_drol | 1.1.2.1 | |
69 : | ////////////////////////////////////////////////////////// | ||
70 : | // Upsampling (1/3/3/1) filter | ||
71 : | |||
72 : | suxen_drol | 1.1.2.3 | #define ADD(dst,src) (dst) = CLIP((dst)+(src), 0, 255) |
73 : | suxen_drol | 1.1.2.1 | |
74 : | static __inline void Filter_31(uint8_t *Dst1, uint8_t *Dst2, | ||
75 : | const int16_t *Src1, const int16_t *Src2) | ||
76 : | { | ||
77 : | /* Src[] is assumed to be >=0. So we can use ">>2" instead of "/2" */ | ||
78 : | int16_t a = (3*Src1[0]+ Src2[0]+2) >> 2; | ||
79 : | int16_t b = ( Src1[0]+3*Src2[0]+2) >> 2; | ||
80 : | suxen_drol | 1.1.2.3 | Dst1[0] = CLIP(a, 0, 255); |
81 : | Dst2[0] = CLIP(b, 0, 255); | ||
82 : | suxen_drol | 1.1.2.1 | } |
83 : | |||
84 : | static __inline void Filter_9331(uint8_t *Dst1, uint8_t *Dst2, | ||
85 : | const int16_t *Src1, const int16_t *Src2) | ||
86 : | { | ||
87 : | /* Src[] is assumed to be >=0. So we can use ">>4" instead of "/16" */ | ||
88 : | int16_t a = (9*Src1[0]+ 3*Src1[1]+ 3*Src2[0] + 1*Src2[1] + 8) >> 4; | ||
89 : | int16_t b = (3*Src1[0]+ 9*Src1[1]+ 1*Src2[0] + 3*Src2[1] + 8) >> 4; | ||
90 : | int16_t c = (3*Src1[0]+ 1*Src1[1]+ 9*Src2[0] + 3*Src2[1] + 8) >> 4; | ||
91 : | int16_t d = (1*Src1[0]+ 3*Src1[1]+ 3*Src2[0] + 9*Src2[1] + 8) >> 4; | ||
92 : | suxen_drol | 1.1.2.3 | Dst1[0] = CLIP(a, 0, 255); |
93 : | Dst1[1] = CLIP(b, 0, 255); | ||
94 : | Dst2[0] = CLIP(c, 0, 255); | ||
95 : | Dst2[1] = CLIP(d, 0, 255); | ||
96 : | suxen_drol | 1.1.2.1 | } |
97 : | |||
98 : | void xvid_Copy_Upsampled_8x8_16To8_C(uint8_t *Dst, const int16_t *Src, const int BpS) | ||
99 : | { | ||
100 : | int x, y; | ||
101 : | |||
102 : | suxen_drol | 1.1.2.3 | Dst[0] = CLIP(Src[0], 0, 255); |
103 : | suxen_drol | 1.1.2.1 | for(x=0; x<7; ++x) Filter_31(Dst+2*x+1, Dst+2*x+2, Src+x, Src+x+1); |
104 : | suxen_drol | 1.1.2.3 | Dst[15] = CLIP(Src[7], 0, 255); |
105 : | suxen_drol | 1.1.2.1 | Dst += BpS; |
106 : | for(y=0; y<7; ++y) { | ||
107 : | uint8_t *const Dst2 = Dst + BpS; | ||
108 : | Filter_31(Dst, Dst2, Src, Src+8); | ||
109 : | for(x=0; x<7; ++x) | ||
110 : | Filter_9331(Dst+2*x+1, Dst2+2*x+1, Src+x, Src+x+8); | ||
111 : | Filter_31(Dst+15, Dst2+15, Src+7, Src+7+8); | ||
112 : | Src += 8; | ||
113 : | Dst += 2*BpS; | ||
114 : | } | ||
115 : | suxen_drol | 1.1.2.3 | Dst[0] = CLIP(Src[0], 0, 255); |
116 : | suxen_drol | 1.1.2.1 | for(x=0; x<7; ++x) Filter_31(Dst+2*x+1, Dst+2*x+2, Src+x, Src+x+1); |
117 : | suxen_drol | 1.1.2.3 | Dst[15] = CLIP(Src[7], 0, 255); |
118 : | suxen_drol | 1.1.2.1 | } |
119 : | |||
120 : | static __inline void Filter_Add_31(uint8_t *Dst1, uint8_t *Dst2, | ||
121 : | const int16_t *Src1, const int16_t *Src2) | ||
122 : | { | ||
123 : | /* Here, we must use "/4", since Src[] is in [-256, 255] */ | ||
124 : | int16_t a = (3*Src1[0]+ Src2[0] + 2) / 4; | ||
125 : | int16_t b = ( Src1[0]+3*Src2[0] + 2) / 4; | ||
126 : | ADD(Dst1[0], a); | ||
127 : | ADD(Dst2[0], b); | ||
128 : | } | ||
129 : | |||
130 : | static __inline void Filter_Add_9331(uint8_t *Dst1, uint8_t *Dst2, | ||
131 : | const int16_t *Src1, const int16_t *Src2) | ||
132 : | { | ||
133 : | int16_t a = (9*Src1[0]+ 3*Src1[1]+ 3*Src2[0] + 1*Src2[1] + 8) / 16; | ||
134 : | int16_t b = (3*Src1[0]+ 9*Src1[1]+ 1*Src2[0] + 3*Src2[1] + 8) / 16; | ||
135 : | int16_t c = (3*Src1[0]+ 1*Src1[1]+ 9*Src2[0] + 3*Src2[1] + 8) / 16; | ||
136 : | int16_t d = (1*Src1[0]+ 3*Src1[1]+ 3*Src2[0] + 9*Src2[1] + 8) / 16; | ||
137 : | ADD(Dst1[0], a); | ||
138 : | ADD(Dst1[1], b); | ||
139 : | ADD(Dst2[0], c); | ||
140 : | ADD(Dst2[1], d); | ||
141 : | } | ||
142 : | |||
143 : | void xvid_Add_Upsampled_8x8_16To8_C(uint8_t *Dst, const int16_t *Src, const int BpS) | ||
144 : | { | ||
145 : | int x, y; | ||
146 : | |||
147 : | ADD(Dst[0], Src[0]); | ||
148 : | for(x=0; x<7; ++x) Filter_Add_31(Dst+2*x+1, Dst+2*x+2, Src+x, Src+x+1); | ||
149 : | ADD(Dst[15], Src[7]); | ||
150 : | Dst += BpS; | ||
151 : | for(y=0; y<7; ++y) { | ||
152 : | uint8_t *const Dst2 = Dst + BpS; | ||
153 : | Filter_Add_31(Dst, Dst2, Src, Src+8); | ||
154 : | for(x=0; x<7; ++x) | ||
155 : | Filter_Add_9331(Dst+2*x+1, Dst2+2*x+1, Src+x, Src+x+8); | ||
156 : | Filter_Add_31(Dst+15, Dst2+15, Src+7, Src+7+8); | ||
157 : | Src += 8; | ||
158 : | Dst += 2*BpS; | ||
159 : | } | ||
160 : | ADD(Dst[0], Src[0]); | ||
161 : | for(x=0; x<7; ++x) Filter_Add_31(Dst+2*x+1, Dst+2*x+2, Src+x, Src+x+1); | ||
162 : | ADD(Dst[15], Src[7]); | ||
163 : | } | ||
164 : | #undef ADD | ||
165 : | |||
166 : | ////////////////////////////////////////////////////////// | ||
167 : | // horizontal and vertical deblocking | ||
168 : | |||
169 : | void xvid_HFilter_31_C(uint8_t *Src1, uint8_t *Src2, int Nb_Blks) | ||
170 : | { | ||
171 : | Nb_Blks *= 8; | ||
172 : | while(Nb_Blks-->0) { | ||
173 : | uint8_t a = ( 3*Src1[0] + 1*Src2[0] + 2 ) >> 2; | ||
174 : | uint8_t b = ( 1*Src1[0] + 3*Src2[0] + 2 ) >> 2; | ||
175 : | *Src1++ = a; | ||
176 : | *Src2++ = b; | ||
177 : | } | ||
178 : | } | ||
179 : | |||
180 : | void xvid_VFilter_31_C(uint8_t *Src1, uint8_t *Src2, const int BpS, int Nb_Blks) | ||
181 : | { | ||
182 : | Nb_Blks *= 8; | ||
183 : | while(Nb_Blks-->0) { | ||
184 : | uint8_t a = ( 3*Src1[0] + 1*Src2[0] + 2 ) >> 2; | ||
185 : | uint8_t b = ( 1*Src1[0] + 3*Src2[0] + 2 ) >> 2; | ||
186 : | *Src1 = a; | ||
187 : | *Src2 = b; | ||
188 : | Src1 += BpS; | ||
189 : | Src2 += BpS; | ||
190 : | } | ||
191 : | } | ||
192 : | |||
193 : | ////////////////////////////////////////////////////////// | ||
194 : | // 16x16 -> 8x8 (1/3/3/1) downsampling | ||
195 : | // | ||
196 : | // Warning! These read 1 pixel outside of the input 16x16 block! | ||
197 : | // | ||
198 : | ////////////////////////////////////////////////////////// | ||
199 : | |||
200 : | void xvid_Filter_18x18_To_8x8_C(int16_t *Dst, const uint8_t *Src, const int BpS) | ||
201 : | { | ||
202 : | int16_t *T, Tmp[18*8]; | ||
203 : | int i, j; | ||
204 : | |||
205 : | T = Tmp; | ||
206 : | Src -= BpS; | ||
207 : | for(j=-1; j<17; j++) { | ||
208 : | for(i=0; i<8; ++i) | ||
209 : | T[i] = Src[2*i-1] + 3*Src[2*i+0] + 3*Src[2*i+1] + Src[2*i+2]; | ||
210 : | T += 8; | ||
211 : | Src += BpS; | ||
212 : | } | ||
213 : | T = Tmp + 8; | ||
214 : | for(j=0; j<8; j++) { | ||
215 : | for(i=0; i<8; ++i) | ||
216 : | Dst[i] = ( T[-8+i] + 3*T[0+i] + 3*T[8+i] + T[16+i] + 32 ) / 64; | ||
217 : | Dst += 8; | ||
218 : | T += 16; | ||
219 : | } | ||
220 : | } | ||
221 : | |||
222 : | void xvid_Filter_Diff_18x18_To_8x8_C(int16_t *Dst, const uint8_t *Src, const int BpS) | ||
223 : | { | ||
224 : | int16_t *T, Tmp[18*8]; | ||
225 : | int i, j; | ||
226 : | |||
227 : | T = Tmp; | ||
228 : | Src -= BpS; | ||
229 : | for(j=-1; j<17; j++) { | ||
230 : | for(i=0; i<8; ++i) | ||
231 : | T[i] = Src[2*i-1] + 3*Src[2*i+0] + 3*Src[2*i+1] + Src[2*i+2]; | ||
232 : | T += 8; | ||
233 : | Src += BpS; | ||
234 : | } | ||
235 : | T = Tmp; | ||
236 : | for(j=0; j<8; j++) { | ||
237 : | for(i=0; i<8; ++i) | ||
238 : | Dst[i] -= ( T[i] + 3*T[8+i] + 3*T[16+i] + T[24+i] + 32 ) / 64; | ||
239 : | Dst += 8; | ||
240 : | T += 16; | ||
241 : | } | ||
242 : | } | ||
243 : | |||
244 : | ////////////////////////////////////////////////////////// |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |