Commit a2f91640 authored by Sam Hocevar's avatar Sam Hocevar

* ./plugins/chroma/i420_yuy2.h: optimized the 420 planar-to-packed chroma

    transformations. They're now PIC-friendly as well.
parent 30a5f368
...@@ -4,6 +4,35 @@ ...@@ -4,6 +4,35 @@
HEAD HEAD
* ./plugins/chroma/i420_yuy2.h: optimized the 420 planar-to-packed chroma
transformations. They're now PIC-friendly as well.
* ./plugins/macosx/intf_open.c: added Open disc and network panels.
* ./plugins/macosx/intf_controller.c: some changes to the control layout.
* ./src/interface/main.c: i_warning_level is set to 0 to avoid unwanted
verbose messages.
* ./po/en_GB.po: British translation.
* ./src/interface/main.c, ./src/misc/configuration.c: fixed the warning_level
handling: "-v" and "--warning" are now working as they should and they also
are cumulative (using -vv --warning=3 you end up with i_warning_level=5).
* ./src/misc/configuration.c: support for short options. -V, -A, -I
are back, and we also have -4 and -6 for IPv4/IPv6.
* ./src/misc/configuration.c: added config_GetFloatVariable() and
config_PutFloatVariable() to the config module.
* ./src/video_output/video_output.c: added a --zoom <float> config option.
* ./plugins/idct/idct_sparse.c: added a call to RestoreCPUState() in
InitIDCT() so that the FPU is still available after a call to InitIDCT().
* ./plugins/text/logger.c: deactivated stream buffering when logging to a
file.
* ./po/*: re-ran make update-po, fixed a few translations.
* ./po/fr.po: completed the french translation.
* ./plugins/gtk/gtk.glade, ./plugins/gtk/gnome.glade: synchronized a few
strings between the Gtk+ and GNOME modules to avoid duplicate translations.
* ./po/de.po: updated german translation. Many thanks to Thomas Graf.
* ./doc/vlc-howto.sgml: URL & mailing-lists corrections.
* ./plugins/gtk/gtk_preferences.c: the last category from the config options
wasn't displayed.
* po/nl.po: updated Netherlands translation of interface.
* po/fr.po: completed french translations.
* ALL: internationalized all configuration strings. * ALL: internationalized all configuration strings.
* ./src/interface/main.c: we now set LC_CTYPE to get the right charset. * ./src/interface/main.c: we now set LC_CTYPE to get the right charset.
* ./src/misc/configuration.c: lots of simplifications in the code. * ./src/misc/configuration.c: lots of simplifications in the code.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* i420_yuy2.c : YUV to YUV conversion module for vlc * i420_yuy2.c : YUV to YUV conversion module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN * Copyright (C) 2000, 2001 VideoLAN
* $Id: i420_yuy2.c,v 1.5 2002/04/19 13:56:10 sam Exp $ * $Id: i420_yuy2.c,v 1.6 2002/04/23 13:47:30 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
...@@ -150,8 +150,8 @@ static int chroma_Init( vout_thread_t *p_vout ) ...@@ -150,8 +150,8 @@ static int chroma_Init( vout_thread_t *p_vout )
default: default:
return -1; return -1;
} }
return 0; return 0;
} }
/***************************************************************************** /*****************************************************************************
...@@ -190,24 +190,12 @@ static void I420_YUY2( vout_thread_t *p_vout, picture_t *p_source, ...@@ -190,24 +190,12 @@ static void I420_YUY2( vout_thread_t *p_vout, picture_t *p_source,
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; ) for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{ {
#if defined (MODULE_NAME_IS_chroma_i420_yuy2) #if defined (MODULE_NAME_IS_chroma_i420_yuy2)
C_YUV420_YUYV( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_YUYV( );
C_YUV420_YUYV( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_YUYV( );
C_YUV420_YUYV( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_YUYV( );
C_YUV420_YUYV( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_YUYV( );
#else #else
__asm__( ".align 8" MMX_YUV420_YUYV MMX_CALL( MMX_YUV420_YUYV );
: : "r" (p_line1), "r" (p_line2),
"r" (p_y1), "r" (p_y2), "r" (p_u), "r" (p_v) );
p_line1 += 8; p_line2 += 8;
p_y1 += 4; p_y2 += 4; p_u += 2; p_v += 2;
__asm__( ".align 8" MMX_YUV420_YUYV
: : "r" (p_line1), "r" (p_line2),
"r" (p_y1), "r" (p_y2), "r" (p_u), "r" (p_v) );
p_line1 += 8; p_line2 += 8;
p_y1 += 4; p_y2 += 4; p_u += 2; p_v += 2;
#endif #endif
} }
} }
...@@ -237,24 +225,12 @@ static void I420_YVYU( vout_thread_t *p_vout, picture_t *p_source, ...@@ -237,24 +225,12 @@ static void I420_YVYU( vout_thread_t *p_vout, picture_t *p_source,
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; ) for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{ {
#if defined (MODULE_NAME_IS_chroma_i420_yuy2) #if defined (MODULE_NAME_IS_chroma_i420_yuy2)
C_YUV420_YVYU( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_YVYU( );
C_YUV420_YVYU( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_YVYU( );
C_YUV420_YVYU( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_YVYU( );
C_YUV420_YVYU( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_YVYU( );
#else #else
__asm__( ".align 8" MMX_YUV420_YVYU MMX_CALL( MMX_YUV420_YVYU );
: : "r" (p_line1), "r" (p_line2),
"r" (p_y1), "r" (p_y2), "r" (p_u), "r" (p_v) );
p_line1 += 8; p_line2 += 8;
p_y1 += 4; p_y2 += 4; p_u += 2; p_v += 2;
__asm__( ".align 8" MMX_YUV420_YVYU
: : "r" (p_line1), "r" (p_line2),
"r" (p_y1), "r" (p_y2), "r" (p_u), "r" (p_v) );
p_line1 += 8; p_line2 += 8;
p_y1 += 4; p_y2 += 4; p_u += 2; p_v += 2;
#endif #endif
} }
} }
...@@ -284,24 +260,12 @@ static void I420_UYVY( vout_thread_t *p_vout, picture_t *p_source, ...@@ -284,24 +260,12 @@ static void I420_UYVY( vout_thread_t *p_vout, picture_t *p_source,
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; ) for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{ {
#if defined (MODULE_NAME_IS_chroma_i420_yuy2) #if defined (MODULE_NAME_IS_chroma_i420_yuy2)
C_YUV420_UYVY( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_UYVY( );
C_YUV420_UYVY( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_UYVY( );
C_YUV420_UYVY( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_UYVY( );
C_YUV420_UYVY( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_UYVY( );
#else #else
__asm__( ".align 8" MMX_YUV420_UYVY MMX_CALL( MMX_YUV420_UYVY );
: : "r" (p_line1), "r" (p_line2),
"r" (p_y1), "r" (p_y2), "r" (p_u), "r" (p_v) );
p_line1 += 8; p_line2 += 8;
p_y1 += 4; p_y2 += 4; p_u += 2; p_v += 2;
__asm__( ".align 8" MMX_YUV420_UYVY
: : "r" (p_line1), "r" (p_line2),
"r" (p_y1), "r" (p_y2), "r" (p_u), "r" (p_v) );
p_line1 += 8; p_line2 += 8;
p_y1 += 4; p_y2 += 4; p_u += 2; p_v += 2;
#endif #endif
} }
} }
...@@ -344,24 +308,12 @@ static void I420_cyuv( vout_thread_t *p_vout, picture_t *p_source, ...@@ -344,24 +308,12 @@ static void I420_cyuv( vout_thread_t *p_vout, picture_t *p_source,
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; ) for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{ {
#if defined (MODULE_NAME_IS_chroma_i420_yuy2) #if defined (MODULE_NAME_IS_chroma_i420_yuy2)
C_YUV420_UYVY( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_UYVY( );
C_YUV420_UYVY( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_UYVY( );
C_YUV420_UYVY( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_UYVY( );
C_YUV420_UYVY( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_UYVY( );
#else #else
__asm__( ".align 8" MMX_YUV420_UYVY MMX_CALL( MMX_YUV420_UYVY );
: : "r" (p_line1), "r" (p_line2),
"r" (p_y1), "r" (p_y2), "r" (p_u), "r" (p_v) );
p_line1 += 8; p_line2 += 8;
p_y1 += 4; p_y2 += 4; p_u += 2; p_v += 2;
__asm__( ".align 8" MMX_YUV420_UYVY
: : "r" (p_line1), "r" (p_line2),
"r" (p_y1), "r" (p_y2), "r" (p_u), "r" (p_v) );
p_line1 += 8; p_line2 += 8;
p_y1 += 4; p_y2 += 4; p_u += 2; p_v += 2;
#endif #endif
} }
} }
...@@ -391,8 +343,8 @@ static void I420_Y211( vout_thread_t *p_vout, picture_t *p_source, ...@@ -391,8 +343,8 @@ static void I420_Y211( vout_thread_t *p_vout, picture_t *p_source,
for( i_x = p_vout->render.i_width / 8 ; i_x-- ; ) for( i_x = p_vout->render.i_width / 8 ; i_x-- ; )
{ {
C_YUV420_Y211( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_Y211( );
C_YUV420_Y211( p_line1, p_line2, p_y1, p_y2, p_u, p_v ); C_YUV420_Y211( );
} }
} }
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* i420_yuy2.h : YUV to YUV conversion module for vlc * i420_yuy2.h : YUV to YUV conversion module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN * Copyright (C) 2000, 2001 VideoLAN
* $Id: i420_yuy2.h,v 1.1 2002/01/04 14:01:34 sam Exp $ * $Id: i420_yuy2.h,v 1.2 2002/04/23 13:47:30 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -28,10 +28,46 @@ ...@@ -28,10 +28,46 @@
UNUSED_LONGLONG(woo_00ffw) = 0x00ff00ff00ff00ff; UNUSED_LONGLONG(woo_00ffw) = 0x00ff00ff00ff00ff;
UNUSED_LONGLONG(woo_80w) = 0x0000000080808080; UNUSED_LONGLONG(woo_80w) = 0x0000000080808080;
#define MMX_CALL(foo) \
__asm__ __volatile__( \
MMX_LOAD \
".align 8 \n\t" \
foo \
MMX_INC \
".align 8 \n\t" \
foo \
MMX_INC \
MMX_SAVE \
: "=c" (p_line1), "=d" (p_line2), "=D" (p_y1), "=S" (p_y2) \
: "c" (p_line1), "d" (p_line2), "D" (p_y1), "S" (p_y2), \
"m" (p_u), "m" (p_v) \
: "eax" );
#define MMX_LOAD " \n\
pushl %%ebx \n\
movl %8,%%eax \n\
movl %9,%%ebx \n\
"
#define MMX_SAVE " \n\
movl %%eax,%8 \n\
movl %%ebx,%9 \n\
popl %%ebx \n\
"
#define MMX_INC " \n\
addl $8, %0 \n\
addl $8, %1 \n\
addl $4, %2 \n\
addl $4, %3 \n\
addl $2, %%eax \n\
addl $2, %%ebx \n\
"
#define MMX_YUV420_YUYV " \n\ #define MMX_YUV420_YUYV " \n\
movq (%2), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\ movq (%2), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\
movd (%4), %%mm1 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\ movd (%%eax), %%mm1 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd (%5), %%mm2 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\ movd (%%ebx), %%mm2 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
punpcklbw %%mm2, %%mm1 # v3 u3 v2 u2 v1 u1 v0 u0 \n\ punpcklbw %%mm2, %%mm1 # v3 u3 v2 u2 v1 u1 v0 u0 \n\
movq %%mm0, %%mm2 # y7 y6 y5 y4 y3 y2 y1 y0 \n\ movq %%mm0, %%mm2 # y7 y6 y5 y4 y3 y2 y1 y0 \n\
punpcklbw %%mm1, %%mm2 # v1 y3 u1 y2 v0 y1 u0 y0 \n\ punpcklbw %%mm1, %%mm2 # v1 y3 u1 y2 v0 y1 u0 y0 \n\
...@@ -48,8 +84,8 @@ movq %%mm0, 8(%1) # Store high YUYV \n\ ...@@ -48,8 +84,8 @@ movq %%mm0, 8(%1) # Store high YUYV \n\
#define MMX_YUV420_YVYU " \n\ #define MMX_YUV420_YVYU " \n\
movq (%2), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\ movq (%2), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\
movd (%4), %%mm2 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\ movd (%%eax), %%mm2 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd (%5), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\ movd (%%ebx), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
punpcklbw %%mm2, %%mm1 # u3 v3 u2 v2 u1 v1 u0 v0 \n\ punpcklbw %%mm2, %%mm1 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
movq %%mm0, %%mm2 # y7 y6 y5 y4 y3 y2 y1 y0 \n\ movq %%mm0, %%mm2 # y7 y6 y5 y4 y3 y2 y1 y0 \n\
punpcklbw %%mm1, %%mm2 # u1 y3 v1 y2 u0 y1 v0 y0 \n\ punpcklbw %%mm1, %%mm2 # u1 y3 v1 y2 u0 y1 v0 y0 \n\
...@@ -67,8 +103,8 @@ movq %%mm0, 8(%1) # Store high YUYV \n\ ...@@ -67,8 +103,8 @@ movq %%mm0, 8(%1) # Store high YUYV \n\
#define MMX_YUV420_UYVY " \n\ #define MMX_YUV420_UYVY " \n\
movq (%2), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\ movq (%2), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\
movq (%3), %%mm3 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\ movq (%3), %%mm3 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
movd (%4), %%mm2 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\ movd (%%eax), %%mm2 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd (%5), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\ movd (%%ebx), %%mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
punpcklbw %%mm2, %%mm1 # u3 v3 u2 v2 u1 v1 u0 v0 \n\ punpcklbw %%mm2, %%mm1 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
movq %%mm1, %%mm2 # u3 v3 u2 v2 u1 v1 u0 v0 \n\ movq %%mm1, %%mm2 # u3 v3 u2 v2 u1 v1 u0 v0 \n\
punpcklbw %%mm0, %%mm2 # y3 v1 y2 u1 y1 v0 y0 u0 \n\ punpcklbw %%mm0, %%mm2 # y3 v1 y2 u1 y1 v0 y0 u0 \n\
...@@ -87,8 +123,8 @@ movq %%mm1, 8(%1) # Store high UYVY \n\ ...@@ -87,8 +123,8 @@ movq %%mm1, 8(%1) # Store high UYVY \n\
#define MMX_YUV420_Y211 " \n\ #define MMX_YUV420_Y211 " \n\
movq (%2), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\ movq (%2), %%mm0 # Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 \n\
movq (%3), %%mm1 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\ movq (%3), %%mm1 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 \n\
movd (%4), %%mm2 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\ movd (%%eax), %%mm2 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0 \n\
movd (%5), %%mm3 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\ movd (%%ebx), %%mm3 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0 \n\
pand woo_00ffw, %%mm0 # get Y even 00 Y6 00 Y4 00 Y2 00 Y0 \n\ pand woo_00ffw, %%mm0 # get Y even 00 Y6 00 Y4 00 Y2 00 Y0 \n\
packuswb %%mm0, %%mm0 # pack Y y6 y4 y2 y0 y6 y4 y2 y0 \n\ packuswb %%mm0, %%mm0 # pack Y y6 y4 y2 y0 y6 y4 y2 y0 \n\
pand woo_00ffw, %%mm2 # get U even 00 u6 00 u4 00 u2 00 u0 \n\ pand woo_00ffw, %%mm2 # get U even 00 u6 00 u4 00 u2 00 u0 \n\
...@@ -107,25 +143,25 @@ movq %%mm1, (%1) # Store YUYV \n\ ...@@ -107,25 +143,25 @@ movq %%mm1, (%1) # Store YUYV \n\
#else #else
#define C_YUV420_YUYV( p_line1, p_line2, p_y1, p_y2, p_u, p_v ) \ #define C_YUV420_YUYV( ) \
*(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \ *(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_u)++; \ *(p_line1)++ = *(p_line2)++ = *(p_u)++; \
*(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \ *(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_v)++; \ *(p_line1)++ = *(p_line2)++ = *(p_v)++; \
#define C_YUV420_YVYU( p_line1, p_line2, p_y1, p_y2, p_u, p_v ) \ #define C_YUV420_YVYU( ) \
*(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \ *(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_v)++; \ *(p_line1)++ = *(p_line2)++ = *(p_v)++; \
*(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \ *(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_u)++; \ *(p_line1)++ = *(p_line2)++ = *(p_u)++; \
#define C_YUV420_UYVY( p_line1, p_line2, p_y1, p_y2, p_u, p_v ) \ #define C_YUV420_UYVY( ) \
*(p_line1)++ = *(p_line2)++ = *(p_u)++; \ *(p_line1)++ = *(p_line2)++ = *(p_u)++; \
*(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \ *(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_v)++; \ *(p_line1)++ = *(p_line2)++ = *(p_v)++; \
*(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \ *(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++; \
#define C_YUV420_Y211( p_line1, p_line2, p_y1, p_y2, p_u, p_v ) \ #define C_YUV420_Y211( ) \
*(p_line1)++ = *(p_y1); ((u16*)p_y1)++; \ *(p_line1)++ = *(p_y1); ((u16*)p_y1)++; \
*(p_line2)++ = *(p_y2); ((u16*)p_y2)++; \ *(p_line2)++ = *(p_y2); ((u16*)p_y2)++; \
*(p_line1)++ = *(p_line2)++ = *(p_u) - 0x80; ((u16*)p_u)++; \ *(p_line1)++ = *(p_line2)++ = *(p_u) - 0x80; ((u16*)p_u)++; \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment