[cvs] / xvidcore / src / image / qpel.c Repository:
ViewVC logotype

Diff of /xvidcore/src/image/qpel.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1, Sat May 3 23:26:42 2003 UTC revision 1.1.2.1, Sat May 3 23:26:42 2003 UTC
# Line 0  Line 1 
1    /**************************************************************************
2     *
3     *      XVID MPEG-4 VIDEO CODEC
4     *  - QPel interpolation -
5     *
6     *      This program 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.
10     *
11     *      This program 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.
15     *
16     *      You should have received a copy of the GNU General Public License
17     *      along with this program; if not, write to the Free Software
18     *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     *
20     *************************************************************************/
21    
22    /**************************************************************************
23     *
24     *      History:
25     *
26     *  22.10.2002  initial coding  - Skal -
27     *
28     *************************************************************************/
29    
30    #ifndef XVID_AUTO_INCLUDE
31    
32    #include "../portab.h"
33    #include "./qpel.h"
34    
35    //////////////////////////////////////////////////////////
36    
37    static const int32_t FIR_Tab_8[9][8] = {
38      { 14, -3,  2, -1,  0,  0,  0,  0 }
39    , { 23, 19, -6,  3, -1,  0,  0,  0 }
40    , { -7, 20, 20, -6,  3, -1,  0,  0 }
41    , {  3, -6, 20, 20, -6,  3, -1,  0 }
42    , { -1,  3, -6, 20, 20, -6,  3, -1 }
43    , {  0, -1,  3, -6, 20, 20, -6,  3 }
44    , {  0,  0, -1,  3, -6, 20, 20, -7 }
45    , {  0,  0,  0, -1,  3, -6, 19, 23 }
46    , {  0,  0,  0,  0, -1,  2, -3, 14 }
47    };
48    
49    static const int32_t FIR_Tab_16[17][16] = {
50      { 14, -3,  2, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
51    , { 23, 19, -6,  3, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
52    , { -7, 20, 20, -6,  3, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
53    , {  3, -6, 20, 20, -6,  3, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
54    , { -1,  3, -6, 20, 20, -6,  3, -1,  0,  0,  0,  0,  0,  0,  0,  0 }
55    , {  0, -1,  3, -6, 20, 20, -6,  3, -1,  0,  0,  0,  0,  0,  0,  0 }
56    , {  0,  0, -1,  3, -6, 20, 20, -6,  3, -1,  0,  0,  0,  0,  0,  0 }
57    , {  0,  0,  0, -1,  3, -6, 20, 20, -6,  3, -1,  0,  0,  0,  0,  0 }
58    , {  0,  0,  0,  0, -1,  3, -6, 20, 20, -6,  3, -1,  0,  0,  0,  0 }
59    , {  0,  0,  0,  0,  0, -1,  3, -6, 20, 20, -6,  3, -1,  0,  0,  0 }
60    , {  0,  0,  0,  0,  0,  0, -1,  3, -6, 20, 20, -6,  3, -1,  0,  0 }
61    , {  0,  0,  0,  0,  0,  0,  0, -1,  3, -6, 20, 20, -6,  3, -1,  0 }
62    , {  0,  0,  0,  0,  0,  0,  0,  0, -1,  3, -6, 20, 20, -6,  3, -1 }
63    , {  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  3, -6, 20, 20, -6,  3 }
64    , {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  3, -6, 20, 20, -7 }
65    , {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  3, -6, 19, 23 }
66    , {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  2, -3, 14 }
67    };
68    
69    //////////////////////////////////////////////////////////
70    // Implementation
71    
72    #define XVID_AUTO_INCLUDE
73    
74      // 16x? filters
75    
76    #define SIZE  16
77    #define TABLE FIR_Tab_16
78    
79    #define STORE(d,s)  (d) = (s)
80    #define FUNC_H      H_Pass_16_C
81    #define FUNC_V      V_Pass_16_C
82    #define FUNC_HA     H_Pass_Avrg_16_C
83    #define FUNC_VA     V_Pass_Avrg_16_C
84    #define FUNC_HA_UP  H_Pass_Avrg_Up_16_C
85    #define FUNC_VA_UP  V_Pass_Avrg_Up_16_C
86    
87    #include __FILE__   /* self-include ourself */
88    
89      // note: B-frame always uses Rnd=0...
90    #define STORE(d,s)  (d) = ( (s)+(d)+1 ) >> 1
91    #define FUNC_H      H_Pass_16_Add_C
92    #define FUNC_V      V_Pass_16_Add_C
93    #define FUNC_HA     H_Pass_Avrg_16_Add_C
94    #define FUNC_VA     V_Pass_Avrg_16_Add_C
95    #define FUNC_HA_UP  H_Pass_Avrg_Up_16_Add_C
96    #define FUNC_VA_UP  V_Pass_Avrg_Up_16_Add_C
97    
98    #include __FILE__   /* self-include ourself */
99    
100    #undef SIZE
101    #undef TABLE
102    
103      // 8x? filters
104    
105    #define SIZE  8
106    #define TABLE FIR_Tab_8
107    
108    #define STORE(d,s)  (d) = (s)
109    #define FUNC_H      H_Pass_8_C
110    #define FUNC_V      V_Pass_8_C
111    #define FUNC_HA     H_Pass_Avrg_8_C
112    #define FUNC_VA     V_Pass_Avrg_8_C
113    #define FUNC_HA_UP  H_Pass_Avrg_Up_8_C
114    #define FUNC_VA_UP  V_Pass_Avrg_Up_8_C
115    
116    #include __FILE__   /* self-include ourself */
117    
118      // note: B-frame always uses Rnd=0...
119    #define STORE(d,s)  (d) = ( (s)+(d)+1 ) >> 1
120    #define FUNC_H      H_Pass_8_Add_C
121    #define FUNC_V      V_Pass_8_Add_C
122    #define FUNC_HA     H_Pass_Avrg_8_Add_C
123    #define FUNC_VA     V_Pass_Avrg_8_Add_C
124    #define FUNC_HA_UP  H_Pass_Avrg_Up_8_Add_C
125    #define FUNC_VA_UP  V_Pass_Avrg_Up_8_Add_C
126    
127    #include __FILE__   /* self-include ourself */
128    
129    #undef SIZE
130    #undef TABLE
131    
132    #undef XVID_AUTO_INCLUDE
133    
134    //////////////////////////////////////////////////////////
135    // general-purpose hooks
136    // TODO: embed in enc/dec structure?
137    
138    XVID_QP_FUNCS *xvid_QP_Funcs = 0;
139    XVID_QP_FUNCS *xvid_QP_Add_Funcs = 0;
140    
141    //////////////////////////////////////////////////////////
142    // plain C impl. declaration
143    // TODO: should be declared elsewhere?
144    
145    XVID_QP_FUNCS xvid_QP_Funcs_C = {
146      H_Pass_16_C,  H_Pass_Avrg_16_C,  H_Pass_Avrg_Up_16_C
147    , V_Pass_16_C,  V_Pass_Avrg_16_C,  V_Pass_Avrg_Up_16_C
148    
149    , H_Pass_8_C,H_Pass_Avrg_8_C,H_Pass_Avrg_Up_8_C
150    , V_Pass_8_C,V_Pass_Avrg_8_C,V_Pass_Avrg_Up_8_C
151    };
152    
153    XVID_QP_FUNCS xvid_QP_Add_Funcs_C = {
154      H_Pass_16_Add_C,  H_Pass_Avrg_16_Add_C,  H_Pass_Avrg_Up_16_Add_C
155    , V_Pass_16_Add_C,  V_Pass_Avrg_16_Add_C,  V_Pass_Avrg_Up_16_Add_C
156    
157    , H_Pass_8_Add_C,H_Pass_Avrg_8_Add_C,H_Pass_Avrg_Up_8_Add_C
158    , V_Pass_8_Add_C,V_Pass_Avrg_8_Add_C,V_Pass_Avrg_Up_8_Add_C
159    };
160    
161    //////////////////////////////////////////////////////////
162    // mmx impl. declaration (cf. qpel_mmx.asm)
163    // TODO: should be declared elsewhere?
164    
165    extern XVID_QP_PASS_SIGNATURE(xvid_H_Pass_16_mmx);
166    extern XVID_QP_PASS_SIGNATURE(xvid_H_Pass_Avrg_16_mmx);
167    extern XVID_QP_PASS_SIGNATURE(xvid_H_Pass_Avrg_Up_16_mmx);
168    extern XVID_QP_PASS_SIGNATURE(xvid_V_Pass_16_mmx);
169    extern XVID_QP_PASS_SIGNATURE(xvid_V_Pass_Avrg_16_mmx);
170    extern XVID_QP_PASS_SIGNATURE(xvid_V_Pass_Avrg_Up_16_mmx);
171    
172    extern XVID_QP_PASS_SIGNATURE(xvid_H_Pass_8_mmx);
173    extern XVID_QP_PASS_SIGNATURE(xvid_H_Pass_Avrg_8_mmx);
174    extern XVID_QP_PASS_SIGNATURE(xvid_H_Pass_Avrg_Up_8_mmx);
175    extern XVID_QP_PASS_SIGNATURE(xvid_V_Pass_8_mmx);
176    extern XVID_QP_PASS_SIGNATURE(xvid_V_Pass_Avrg_8_mmx);
177    extern XVID_QP_PASS_SIGNATURE(xvid_V_Pass_Avrg_Up_8_mmx);
178    
179    XVID_QP_FUNCS xvid_QP_Funcs_mmx = {
180      xvid_H_Pass_16_mmx,  xvid_H_Pass_Avrg_16_mmx,  xvid_H_Pass_Avrg_Up_16_mmx
181    , xvid_V_Pass_16_mmx,  xvid_V_Pass_Avrg_16_mmx,  xvid_V_Pass_Avrg_Up_16_mmx
182    
183    , xvid_H_Pass_8_mmx,xvid_H_Pass_Avrg_8_mmx,xvid_H_Pass_Avrg_Up_8_mmx
184    , xvid_V_Pass_8_mmx,xvid_V_Pass_Avrg_8_mmx,xvid_V_Pass_Avrg_Up_8_mmx
185    };
186    
187    extern XVID_QP_PASS_SIGNATURE(xvid_H_Pass_Add_16_mmx);
188    extern XVID_QP_PASS_SIGNATURE(xvid_H_Pass_Avrg_Add_16_mmx);
189    extern XVID_QP_PASS_SIGNATURE(xvid_H_Pass_Avrg_Up_Add_16_mmx);
190    extern XVID_QP_PASS_SIGNATURE(xvid_V_Pass_Add_16_mmx);
191    extern XVID_QP_PASS_SIGNATURE(xvid_V_Pass_Avrg_Add_16_mmx);
192    extern XVID_QP_PASS_SIGNATURE(xvid_V_Pass_Avrg_Up_Add_16_mmx);
193    
194    extern XVID_QP_PASS_SIGNATURE(xvid_H_Pass_8_Add_mmx);
195    extern XVID_QP_PASS_SIGNATURE(xvid_H_Pass_Avrg_8_Add_mmx);
196    extern XVID_QP_PASS_SIGNATURE(xvid_H_Pass_Avrg_Up_8_Add_mmx);
197    extern XVID_QP_PASS_SIGNATURE(xvid_V_Pass_8_Add_mmx);
198    extern XVID_QP_PASS_SIGNATURE(xvid_V_Pass_Avrg_8_Add_mmx);
199    extern XVID_QP_PASS_SIGNATURE(xvid_V_Pass_Avrg_Up_8_Add_mmx);
200    
201    XVID_QP_FUNCS xvid_QP_Add_Funcs_mmx = {
202      xvid_H_Pass_Add_16_mmx,  xvid_H_Pass_Avrg_Add_16_mmx,  xvid_H_Pass_Avrg_Up_Add_16_mmx
203    , xvid_V_Pass_Add_16_mmx,  xvid_V_Pass_Avrg_Add_16_mmx,  xvid_V_Pass_Avrg_Up_Add_16_mmx
204    
205    , xvid_H_Pass_8_Add_mmx,xvid_H_Pass_Avrg_8_Add_mmx,xvid_H_Pass_Avrg_Up_8_Add_mmx
206    , xvid_V_Pass_8_Add_mmx,xvid_V_Pass_Avrg_8_Add_mmx,xvid_V_Pass_Avrg_Up_8_Add_mmx
207    };
208    
209    //////////////////////////////////////////////////////////
210    // tables for ASM
211    
212    extern uint16_t xvid_Expand_mmx[256][4]; // 8b -> 64b expansion table
213    
214      // Alternate way of filtering (cf. USE_TABLES flag in qpel_mmx.asm)
215      //
216      // 17 tables, 2K each => 34K
217      // Mirroring can be acheived composing 11 basic tables
218      // (for instance: (23,19,-6,3)=(20,20,-6,3)+(3,-1,0,0)
219      // Using Symmetries (and bswap) could reduce further
220      // the memory to 7 tables (->14K).
221    
222    extern int16_t xvid_FIR_1_0_0_0[256][4];
223    extern int16_t xvid_FIR_3_1_0_0[256][4];
224    extern int16_t xvid_FIR_6_3_1_0[256][4];
225    extern int16_t xvid_FIR_14_3_2_1[256][4];
226    extern int16_t xvid_FIR_20_6_3_1[256][4];
227    extern int16_t xvid_FIR_20_20_6_3[256][4];
228    extern int16_t xvid_FIR_23_19_6_3[256][4];
229    extern int16_t xvid_FIR_7_20_20_6[256][4];
230    extern int16_t xvid_FIR_6_20_20_6[256][4];
231    extern int16_t xvid_FIR_6_20_20_7[256][4];
232    extern int16_t xvid_FIR_3_6_20_20[256][4];
233    extern int16_t xvid_FIR_3_6_19_23[256][4];
234    extern int16_t xvid_FIR_1_3_6_20[256][4];
235    extern int16_t xvid_FIR_1_2_3_14[256][4];
236    extern int16_t xvid_FIR_0_1_3_6[256][4];
237    extern int16_t xvid_FIR_0_0_1_3[256][4];
238    extern int16_t xvid_FIR_0_0_0_1[256][4];
239    
240    //////////////////////////////////////////////////////////
241    
242    uint16_t xvid_Expand_mmx[256][4]; // 8b -> 64b expansion table
243    
244    int16_t xvid_FIR_1_0_0_0[256][4];
245    int16_t xvid_FIR_3_1_0_0[256][4];
246    int16_t xvid_FIR_6_3_1_0[256][4];
247    int16_t xvid_FIR_14_3_2_1[256][4];
248    int16_t xvid_FIR_20_6_3_1[256][4];
249    int16_t xvid_FIR_20_20_6_3[256][4];
250    int16_t xvid_FIR_23_19_6_3[256][4];
251    int16_t xvid_FIR_7_20_20_6[256][4];
252    int16_t xvid_FIR_6_20_20_6[256][4];
253    int16_t xvid_FIR_6_20_20_7[256][4];
254    int16_t xvid_FIR_3_6_20_20[256][4];
255    int16_t xvid_FIR_3_6_19_23[256][4];
256    int16_t xvid_FIR_1_3_6_20[256][4];
257    int16_t xvid_FIR_1_2_3_14[256][4];
258    int16_t xvid_FIR_0_1_3_6[256][4];
259    int16_t xvid_FIR_0_0_1_3[256][4];
260    int16_t xvid_FIR_0_0_0_1[256][4];
261    
262    static void Init_FIR_Table(int16_t Tab[][4],
263                               int A, int B, int C, int D)
264    {
265      int i;
266      for(i=0; i<256; ++i) {
267        Tab[i][0] = i*A;
268        Tab[i][1] = i*B;
269        Tab[i][2] = i*C;
270        Tab[i][3] = i*D;
271      }
272    }
273    
274    
275    void xvid_Init_QP_mmx()
276    {
277      int i;
278      for(i=0; i<256; ++i) {
279        xvid_Expand_mmx[i][0] = i;
280        xvid_Expand_mmx[i][1] = i;
281        xvid_Expand_mmx[i][2] = i;
282        xvid_Expand_mmx[i][3] = i;
283      }
284    
285      // Alternate way of filtering (cf. USE_TABLES flag in qpel_mmx.asm)
286    
287      Init_FIR_Table(xvid_FIR_1_0_0_0,   -1,  0,  0,  0);
288      Init_FIR_Table(xvid_FIR_3_1_0_0,    3, -1,  0,  0);
289      Init_FIR_Table(xvid_FIR_6_3_1_0,   -6,  3, -1,  0);
290      Init_FIR_Table(xvid_FIR_14_3_2_1,  14, -3,  2, -1);
291      Init_FIR_Table(xvid_FIR_20_6_3_1,  20, -6,  3, -1);
292      Init_FIR_Table(xvid_FIR_20_20_6_3, 20, 20, -6,  3);
293      Init_FIR_Table(xvid_FIR_23_19_6_3, 23, 19, -6,  3);
294      Init_FIR_Table(xvid_FIR_7_20_20_6, -7, 20, 20, -6);
295      Init_FIR_Table(xvid_FIR_6_20_20_6, -6, 20, 20, -6);
296      Init_FIR_Table(xvid_FIR_6_20_20_7, -6, 20, 20, -7);
297      Init_FIR_Table(xvid_FIR_3_6_20_20,  3, -6, 20, 20);
298      Init_FIR_Table(xvid_FIR_3_6_19_23,  3, -6, 19, 23);
299      Init_FIR_Table(xvid_FIR_1_3_6_20,  -1,  3, -6, 20);
300      Init_FIR_Table(xvid_FIR_1_2_3_14,  -1,  2, -3, 14);
301      Init_FIR_Table(xvid_FIR_0_1_3_6,    0, -1,  3, -6);
302      Init_FIR_Table(xvid_FIR_0_0_1_3,    0,  0, -1,  3);
303      Init_FIR_Table(xvid_FIR_0_0_0_1,    0,  0,  0, -1);
304    
305    }
306    
307    #endif /* !XVID_AUTO_INCLUDE */
308    
309    //////////////////////////////////////////////////////////
310    // "reference" filters impl. in plain C
311    //////////////////////////////////////////////////////////
312    
313    #ifdef XVID_AUTO_INCLUDE
314    
315    static
316    void FUNC_H(uint8_t *Dst, const uint8_t *Src, int32_t H, int32_t BpS, int32_t Rnd)
317    {
318      while(H-->0) {
319        int32_t i, k;
320        int32_t Sums[SIZE] = { 0 };
321        for(i=0; i<=SIZE; ++i)
322          for(k=0; k<SIZE; ++k)
323            Sums[k] += TABLE[i][k] * Src[i];
324    
325        for(i=0; i<SIZE; ++i) {
326          int32_t C = ( Sums[i] + 16-Rnd ) >> 5;
327          if (C<0) C = 0; else if (C>255) C = 255;
328          STORE(Dst[i], C);
329        }
330        Src += BpS;
331        Dst += BpS;
332      }
333    }
334    
335    static
336    void FUNC_V(uint8_t *Dst, const uint8_t *Src, int32_t W, int32_t BpS, int32_t Rnd)
337    {
338      while(W-->0) {
339        int32_t i, k;
340        int32_t Sums[SIZE] = { 0 };
341        const uint8_t *S = Src++;
342        uint8_t *D = Dst++;
343        for(i=0; i<=SIZE; ++i) {
344          for(k=0; k<SIZE; ++k)
345            Sums[k] += TABLE[i][k] * S[0];
346          S += BpS;
347        }
348    
349        for(i=0; i<SIZE; ++i) {
350          int32_t C = ( Sums[i] + 16-Rnd )>>5;
351          if (C<0) C = 0; else if (C>255) C = 255;
352          STORE(D[0], C);
353          D += BpS;
354        }
355      }
356    }
357    
358    static
359    void FUNC_HA(uint8_t *Dst, const uint8_t *Src, int32_t H, int32_t BpS, int32_t Rnd)
360    {
361      while(H-->0) {
362        int32_t i, k;
363        int32_t Sums[SIZE] = { 0 };
364        for(i=0; i<=SIZE; ++i)
365          for(k=0; k<SIZE; ++k)
366            Sums[k] += TABLE[i][k] * Src[i];
367    
368        for(i=0; i<SIZE; ++i) {
369          int32_t C = ( Sums[i] + 16-Rnd ) >> 5;
370          if (C<0) C = 0; else if (C>255) C = 255;
371          C = (C+Src[i]+1-Rnd) >> 1;
372          STORE(Dst[i], C);
373        }
374        Src += BpS;
375        Dst += BpS;
376      }
377    }
378    
379    static
380    void FUNC_HA_UP(uint8_t *Dst, const uint8_t *Src, int32_t H, int32_t BpS, int32_t Rnd)
381    {
382      while(H-->0) {
383        int32_t i, k;
384        int32_t Sums[SIZE] = { 0 };
385        for(i=0; i<=SIZE; ++i)
386          for(k=0; k<SIZE; ++k)
387            Sums[k] += TABLE[i][k] * Src[i];
388    
389        for(i=0; i<SIZE; ++i) {
390          int32_t C = ( Sums[i] + 16-Rnd ) >> 5;
391          if (C<0) C = 0; else if (C>255) C = 255;
392          C = (C+Src[i+1]+1-Rnd) >> 1;
393          STORE(Dst[i], C);
394        }
395        Src += BpS;
396        Dst += BpS;
397      }
398    }
399    
400    static
401    void FUNC_VA(uint8_t *Dst, const uint8_t *Src, int32_t W, int32_t BpS, int32_t Rnd)
402    {
403      while(W-->0) {
404        int32_t i, k;
405        int32_t Sums[SIZE] = { 0 };
406        const uint8_t *S = Src;
407        uint8_t *D = Dst;
408    
409        for(i=0; i<=SIZE; ++i) {
410          for(k=0; k<SIZE; ++k)
411            Sums[k] += TABLE[i][k] * S[0];
412          S += BpS;
413        }
414    
415        S = Src;
416        for(i=0; i<SIZE; ++i) {
417          int32_t C = ( Sums[i] + 16-Rnd )>>5;
418          if (C<0) C = 0; else if (C>255) C = 255;
419          C = ( C+S[0]+1-Rnd ) >> 1;
420          STORE(D[0], C);
421          D += BpS;
422          S += BpS;
423        }
424        Src++;
425        Dst++;
426      }
427    }
428    
429    static
430    void FUNC_VA_UP(uint8_t *Dst, const uint8_t *Src, int32_t W, int32_t BpS, int32_t Rnd)
431    {
432      while(W-->0) {
433        int32_t i, k;
434        int32_t Sums[SIZE] = { 0 };
435        const uint8_t *S = Src;
436        uint8_t *D = Dst;
437    
438        for(i=0; i<=SIZE; ++i) {
439          for(k=0; k<SIZE; ++k)
440            Sums[k] += TABLE[i][k] * S[0];
441          S += BpS;
442        }
443    
444        S = Src + BpS;
445        for(i=0; i<SIZE; ++i) {
446          int32_t C = ( Sums[i] + 16-Rnd )>>5;
447          if (C<0) C = 0; else if (C>255) C = 255;
448          C = ( C+S[0]+1-Rnd ) >> 1;
449          STORE(D[0], C);
450          D += BpS;
451          S += BpS;
452        }
453        Dst++;
454        Src++;
455      }
456    }
457    
458    #undef STORE
459    #undef FUNC_H
460    #undef FUNC_V
461    #undef FUNC_HA
462    #undef FUNC_VA
463    #undef FUNC_HA_UP
464    #undef FUNC_VA_UP
465    
466    #endif /* XVID_AUTO_INCLUDE */
467    
468    //////////////////////////////////////////////////////////

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.1

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4