Commit a69f01ce authored by Sam Hocevar's avatar Sam Hocevar

. am�lioration de la YUV 8bpp

 . nettoyage du code de gestion des m�thodes vout
 . nouvelle option --vout
 . pr�paration de l'�clatage de l'audio output comme �a a �t�
  fait avec le vout.
 . nouvelle commande --long-help

La s�lection de la m�thode vout est encore plus simple. Pour s�lectionner
le framebuffer par exemple : "vlc --vout fb". Par d�faut, X11 est choisi.
parent 89a64c61
...@@ -13,14 +13,15 @@ ...@@ -13,14 +13,15 @@
#CC=gcc #CC=gcc
#SHELL=/bin/sh #SHELL=/bin/sh
# Audio output settings
AUDIO_DSP=YES
# Video output settings # Video output settings
VIDEO_X11=YES VIDEO_X11=YES
VIDEO_FB=YES VIDEO_FB=YES
#VIDEO_GGI=YES #VIDEO_GGI=YES
# You probably won't need this one
# Highly experimental
#VIDEO_GLIDE=YES #VIDEO_GLIDE=YES
# Not yet supported # Not yet supported
#VIDEO_BEOS=YES #VIDEO_BEOS=YES
#VIDEO_DGA=YES #VIDEO_DGA=YES
...@@ -55,6 +56,15 @@ DEBUG=1 ...@@ -55,6 +56,15 @@ DEBUG=1
# Program version - may only be changed by the project leader # Program version - may only be changed by the project leader
PROGRAM_VERSION = 1.0-dev PROGRAM_VERSION = 1.0-dev
# AUDIO_OPTIONS describes all used audio options
AUDIO_OPTIONS = dummy
aout_method = audio_output/aout_dummy.o
ifeq ($(AUDIO_DSP), YES)
AUDIO_OPTIONS += dsp
DEFINE += -DAUDIO_DSP
aout_method += audio_output/aout_dsp.o
endif
# VIDEO_OPTIONS describes all used video options # VIDEO_OPTIONS describes all used video options
VIDEO_OPTIONS = dummy VIDEO_OPTIONS = dummy
intf_method = interface/intf_dummy.o intf_method = interface/intf_dummy.o
...@@ -109,7 +119,8 @@ PROGRAM_BUILD = `date -R` $(USER)@`hostname` ...@@ -109,7 +119,8 @@ PROGRAM_BUILD = `date -R` $(USER)@`hostname`
# including ARCH_xx and SYS_xx. It will be passed to C compiler. # including ARCH_xx and SYS_xx. It will be passed to C compiler.
DEFINE += -DARCH_$(ARCH) DEFINE += -DARCH_$(ARCH)
DEFINE += -DSYS_$(SYS) DEFINE += -DSYS_$(SYS)
DEFINE += -DVIDEO_OPTIONS="\"$(VIDEO_OPTIONS)\"" DEFINE += -DAUDIO_OPTIONS="\"$(shell echo $(AUDIO_OPTIONS) | tr 'A-Z' 'a-z')\""
DEFINE += -DVIDEO_OPTIONS="\"$(shell echo $(VIDEO_OPTIONS) | tr 'A-Z' 'a-z')\""
DEFINE += -DPROGRAM_VERSION="\"$(PROGRAM_VERSION)\"" DEFINE += -DPROGRAM_VERSION="\"$(PROGRAM_VERSION)\""
DEFINE += -DPROGRAM_OPTIONS="\"$(PROGRAM_OPTIONS)\"" DEFINE += -DPROGRAM_OPTIONS="\"$(PROGRAM_OPTIONS)\""
DEFINE += -DPROGRAM_BUILD="\"$(PROGRAM_BUILD)\"" DEFINE += -DPROGRAM_BUILD="\"$(PROGRAM_BUILD)\""
...@@ -117,9 +128,6 @@ ifeq ($(DEBUG),1) ...@@ -117,9 +128,6 @@ ifeq ($(DEBUG),1)
DEFINE += -DDEBUG DEFINE += -DDEBUG
endif endif
# video is a lowercase version of VIDEO used for filenames
video = $(shell echo $(VIDEO) | tr 'A-Z' 'a-z')
################################################################################ ################################################################################
# Tuning and other variables - do not change anything except if you know # Tuning and other variables - do not change anything except if you know
# exactly what you are doing # exactly what you are doing
......
...@@ -206,6 +206,9 @@ ...@@ -206,6 +206,9 @@
* Audio configuration * Audio configuration
*****************************************************************************/ *****************************************************************************/
/* Environment variable containing the audio output method */
#define AOUT_METHOD_VAR "vlc_aout"
/* Environment variable used to store dsp device name, and default value */ /* Environment variable used to store dsp device name, and default value */
#define AOUT_DSP_VAR "vlc_dsp" #define AOUT_DSP_VAR "vlc_dsp"
#define AOUT_DSP_DEFAULT "/dev/dsp" #define AOUT_DSP_DEFAULT "/dev/dsp"
...@@ -227,7 +230,7 @@ ...@@ -227,7 +230,7 @@
*/ */
/* Environment variable containing the display method */ /* Environment variable containing the display method */
#define VOUT_METHOD_VAR "vlc_vout_method" #define VOUT_METHOD_VAR "vlc_vout"
/* Environment variable used in place of DISPLAY if available */ /* Environment variable used in place of DISPLAY if available */
#define VOUT_DISPLAY_VAR "vlc_display" #define VOUT_DISPLAY_VAR "vlc_display"
......
...@@ -36,19 +36,25 @@ ...@@ -36,19 +36,25 @@
/* Long options return values - note that values corresponding to short options /* Long options return values - note that values corresponding to short options
* chars, and in general any regular char, should be avoided */ * chars, and in general any regular char, should be avoided */
#define OPT_NOAUDIO 150 #define OPT_NOAUDIO 150
#define OPT_STEREO 151 #define OPT_AOUT 151
#define OPT_MONO 152 #define OPT_STEREO 152
#define OPT_MONO 153
#define OPT_NOVIDEO 160 #define OPT_NOVIDEO 160
#define OPT_DISPLAY 161 #define OPT_VOUT 161
#define OPT_WIDTH 162 #define OPT_DISPLAY 162
#define OPT_HEIGHT 163 #define OPT_WIDTH 163
#define OPT_COLOR 164 #define OPT_HEIGHT 164
#define OPT_COLOR 165
#define OPT_NOVLANS 170 #define OPT_NOVLANS 170
#define OPT_SERVER 171 #define OPT_SERVER 171
#define OPT_PORT 172 #define OPT_PORT 172
/* Usage fashion */
#define SHORT_HELP 0
#define LONG_HELP 1
/* Long options */ /* Long options */
static const struct option longopts[] = static const struct option longopts[] =
{ {
...@@ -56,15 +62,18 @@ static const struct option longopts[] = ...@@ -56,15 +62,18 @@ static const struct option longopts[] =
/* General/common options */ /* General/common options */
{ "help", 0, 0, 'h' }, { "help", 0, 0, 'h' },
{ "long-help", 0, 0, 'H' },
{ "version", 0, 0, 'v' }, { "version", 0, 0, 'v' },
/* Audio options */ /* Audio options */
{ "noaudio", 0, 0, OPT_NOAUDIO }, { "noaudio", 0, 0, OPT_NOAUDIO },
{ "aout", 1, 0, OPT_AOUT },
{ "stereo", 0, 0, OPT_STEREO }, { "stereo", 0, 0, OPT_STEREO },
{ "mono", 0, 0, OPT_MONO }, { "mono", 0, 0, OPT_MONO },
/* Video options */ /* Video options */
{ "novideo", 0, 0, OPT_NOVIDEO }, { "novideo", 0, 0, OPT_NOVIDEO },
{ "vout", 1, 0, OPT_VOUT },
{ "display", 1, 0, OPT_DISPLAY }, { "display", 1, 0, OPT_DISPLAY },
{ "width", 1, 0, OPT_WIDTH }, { "width", 1, 0, OPT_WIDTH },
{ "height", 1, 0, OPT_HEIGHT }, { "height", 1, 0, OPT_HEIGHT },
...@@ -80,7 +89,7 @@ static const struct option longopts[] = ...@@ -80,7 +89,7 @@ static const struct option longopts[] =
}; };
/* Short options */ /* Short options */
static const char *psz_shortopts = "hvg"; static const char *psz_shortopts = "hHvg";
/***************************************************************************** /*****************************************************************************
* Global variable program_data - this is the one and only, see main.h * Global variable program_data - this is the one and only, see main.h
...@@ -92,7 +101,7 @@ main_t *p_main; ...@@ -92,7 +101,7 @@ main_t *p_main;
*****************************************************************************/ *****************************************************************************/
static void SetDefaultConfiguration ( void ); static void SetDefaultConfiguration ( void );
static int GetConfiguration ( int i_argc, char *ppsz_argv[], char *ppsz_env[] ); static int GetConfiguration ( int i_argc, char *ppsz_argv[], char *ppsz_env[] );
static void Usage ( void ); static void Usage ( int i_fashion );
static void Version ( void ); static void Version ( void );
static void InitSignalHandler ( void ); static void InitSignalHandler ( void );
...@@ -144,7 +153,7 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) ...@@ -144,7 +153,7 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
if( main_data.b_vlans && input_VlanCreate() ) if( main_data.b_vlans && input_VlanCreate() )
{ {
/* On error during vlans initialization, switch of vlans */ /* On error during vlans initialization, switch of vlans */
intf_Msg("Virtual LANs initialization failed : vlans management is desactivated\n"); intf_Msg("Virtual LANs initialization failed : vlans management is deactivated\n");
main_data.b_vlans = 0; main_data.b_vlans = 0;
} }
...@@ -157,7 +166,7 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) ...@@ -157,7 +166,7 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
if( main_data.p_aout == NULL ) if( main_data.p_aout == NULL )
{ {
/* On error during audio initialization, switch of audio */ /* On error during audio initialization, switch of audio */
intf_Msg("Audio initialization failed : audio is desactivated\n"); intf_Msg("Audio initialization failed : audio is deactivated\n");
main_data.b_audio = 0; main_data.b_audio = 0;
} }
} }
...@@ -325,7 +334,11 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) ...@@ -325,7 +334,11 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
{ {
/* General/common options */ /* General/common options */
case 'h': /* -h, --help */ case 'h': /* -h, --help */
Usage(); Usage( SHORT_HELP );
return( -1 );
break;
case 'H': /* -H, --long-help */
Usage( LONG_HELP );
return( -1 ); return( -1 );
break; break;
case 'v': /* -v, --version */ case 'v': /* -v, --version */
...@@ -337,6 +350,9 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) ...@@ -337,6 +350,9 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
case OPT_NOAUDIO: /* --noaudio */ case OPT_NOAUDIO: /* --noaudio */
p_main->b_audio = 0; p_main->b_audio = 0;
break; break;
case OPT_AOUT: /* --aout */
main_PutPszVariable( AOUT_METHOD_VAR, optarg );
break;
case OPT_STEREO: /* --stereo */ case OPT_STEREO: /* --stereo */
main_PutIntVariable( AOUT_STEREO_VAR, 1 ); main_PutIntVariable( AOUT_STEREO_VAR, 1 );
break; break;
...@@ -348,6 +364,9 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) ...@@ -348,6 +364,9 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
case OPT_NOVIDEO: /* --novideo */ case OPT_NOVIDEO: /* --novideo */
p_main->b_video = 0; p_main->b_video = 0;
break; break;
case OPT_VOUT: /* --vout */
main_PutPszVariable( VOUT_METHOD_VAR, optarg );
break;
case OPT_DISPLAY: /* --display */ case OPT_DISPLAY: /* --display */
main_PutPszVariable( VOUT_DISPLAY_VAR, optarg ); main_PutPszVariable( VOUT_DISPLAY_VAR, optarg );
break; break;
...@@ -398,7 +417,7 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) ...@@ -398,7 +417,7 @@ static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
***************************************************************************** *****************************************************************************
* Print a short inline help. Message interface is initialized at this stage. * Print a short inline help. Message interface is initialized at this stage.
*****************************************************************************/ *****************************************************************************/
static void Usage( void ) static void Usage( int i_fashion )
{ {
intf_Msg(COPYRIGHT_MESSAGE "\n"); intf_Msg(COPYRIGHT_MESSAGE "\n");
...@@ -407,9 +426,12 @@ static void Usage( void ) ...@@ -407,9 +426,12 @@ static void Usage( void )
/* Options */ /* Options */
intf_Msg("Options:\n" \ intf_Msg("Options:\n" \
" -h, --help, -v, --version \tprint usage or version\n" \ " -h, --help, -H, --long-help \tprint short/long usage\n" \
" -v, --version \tprint version information\n" \
" --noaudio, --novideo \tdisable audio/video\n" \ " --noaudio, --novideo \tdisable audio/video\n" \
" --aout {" AUDIO_OPTIONS "} \taudio output method\n" \
" --stereo, --mono \tstereo/mono audio\n" \ " --stereo, --mono \tstereo/mono audio\n" \
" --vout {" VIDEO_OPTIONS "} \tvideo output method\n" \
" --display <display> \tdisplay string\n" \ " --display <display> \tdisplay string\n" \
" --width <w>, --height <h> \tdisplay dimensions\n" \ " --width <w>, --height <h> \tdisplay dimensions\n" \
" -g, --grayscale, --color \tgrayscale/color video\n" \ " -g, --grayscale, --color \tgrayscale/color video\n" \
...@@ -417,6 +439,9 @@ static void Usage( void ) ...@@ -417,6 +439,9 @@ static void Usage( void )
" --server <host>, --port <port> \tvideo server adress\n" \ " --server <host>, --port <port> \tvideo server adress\n" \
); );
if( i_fashion == SHORT_HELP )
return;
/* Interface parameters */ /* Interface parameters */
intf_Msg("Interface parameters:\n" \ intf_Msg("Interface parameters:\n" \
" " INTF_INIT_SCRIPT_VAR "=<filename> \tinitialization script\n" \ " " INTF_INIT_SCRIPT_VAR "=<filename> \tinitialization script\n" \
...@@ -425,6 +450,7 @@ static void Usage( void ) ...@@ -425,6 +450,7 @@ static void Usage( void )
/* Audio parameters */ /* Audio parameters */
intf_Msg("Audio parameters:\n" \ intf_Msg("Audio parameters:\n" \
" " AOUT_METHOD_VAR "=<method name> \taudio method (" AUDIO_OPTIONS ")\n" \
" " AOUT_DSP_VAR "=<filename> \tdsp device path\n" \ " " AOUT_DSP_VAR "=<filename> \tdsp device path\n" \
" " AOUT_STEREO_VAR "={1|0} \tstereo or mono output\n" \ " " AOUT_STEREO_VAR "={1|0} \tstereo or mono output\n" \
" " AOUT_RATE_VAR "=<rate> \toutput rate\n" \ " " AOUT_RATE_VAR "=<rate> \toutput rate\n" \
...@@ -432,8 +458,7 @@ static void Usage( void ) ...@@ -432,8 +458,7 @@ static void Usage( void )
/* Video parameters */ /* Video parameters */
intf_Msg("Video parameters:\n" \ intf_Msg("Video parameters:\n" \
" " VOUT_METHOD_VAR "=<method name> \tmethod used\n" \ " " VOUT_METHOD_VAR "=<method name> \tdisplay method (" VIDEO_OPTIONS ")\n" \
" ( available: " VIDEO_OPTIONS " )\n" \
" " VOUT_DISPLAY_VAR "=<display name> \tdisplay used\n" \ " " VOUT_DISPLAY_VAR "=<display name> \tdisplay used\n" \
" " VOUT_WIDTH_VAR "=<width> \tdisplay width\n" \ " " VOUT_WIDTH_VAR "=<width> \tdisplay width\n" \
" " VOUT_HEIGHT_VAR "=<height> \tdislay height\n" \ " " VOUT_HEIGHT_VAR "=<height> \tdislay height\n" \
......
...@@ -28,39 +28,6 @@ ...@@ -28,39 +28,6 @@
* Constants * Constants
*****************************************************************************/ *****************************************************************************/
/* Color masks for different color depths - 8bpp masks can be choosen, since
* colormaps instead of hardware-defined colors are used. */
//?? remove
#define RED_8BPP_MASK 0xe0
#define GREEN_8BPP_MASK 0x1c
#define BLUE_8BPP_MASK 0x03
#define RED_15BPP_MASK 0xf800
#define GREEN_15BPP_MASK 0x03e0
#define BLUE_15BPP_MASK 0x001f
#define RED_16BPP_MASK 0xf800
#define GREEN_16BPP_MASK 0x07e0
#define BLUE_16BPP_MASK 0x001f
#define RED_24BPP_MASK 0xff0000
#define GREEN_24BPP_MASK 0x00ff00
#define BLUE_24BPP_MASK 0x0000ff
/* RGB/YUV inversion matrix (ISO/IEC 13818-2 section 6.3.6, table 6.9) */
//?? no more used ?
const int MATRIX_COEFFICIENTS_TABLE[8][4] =
{
{117504, 138453, 13954, 34903}, /* no sequence_display_extension */
{117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */
{104597, 132201, 25675, 53279}, /* unspecified */
{104597, 132201, 25675, 53279}, /* reserved */
{104448, 132798, 24759, 53109}, /* FCC */
{104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */
{104597, 132201, 25675, 53279}, /* SMPTE 170M */
{117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */
};
/* Margins and offsets in conversion tables - Margins are used in case a RGB /* Margins and offsets in conversion tables - Margins are used in case a RGB
* RGB conversion would give a value outside the 0-255 range. Offsets have been * RGB conversion would give a value outside the 0-255 range. Offsets have been
* calculated to avoid using the same cache line for 2 tables. conversion tables * calculated to avoid using the same cache line for 2 tables. conversion tables
...@@ -78,7 +45,7 @@ const int MATRIX_COEFFICIENTS_TABLE[8][4] = ...@@ -78,7 +45,7 @@ const int MATRIX_COEFFICIENTS_TABLE[8][4] =
#define PALETTE_TABLE_SIZE 2176 /* YUV -> 8bpp palette lookup table */ #define PALETTE_TABLE_SIZE 2176 /* YUV -> 8bpp palette lookup table */
//?? /* macros used for YUV pixel conversions */
#define SHIFT 20 #define SHIFT 20
#define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164)) #define U_GREEN_COEF ((int)(-0.391 * (1<<SHIFT) / 1.164))
#define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164)) #define U_BLUE_COEF ((int)(2.018 * (1<<SHIFT) / 1.164))
...@@ -609,10 +576,7 @@ static void SetYUV( vout_thread_t *p_vout ) ...@@ -609,10 +576,7 @@ static void SetYUV( vout_thread_t *p_vout )
{ {
#define RGB_MIN 0 #define RGB_MIN 0
#define RGB_MAX 255 #define RGB_MAX 255
#define SATURATE( x ) \ #define CLIP( x ) ( ((x < 0) ? 0 : (x > 255) ? 255 : x) << 8 )
x = x + ( x >> 3 ) - 16; \
if( x < 0 ) x = 0; \
if( x > 255 ) x = 255;
int y,u,v; int y,u,v;
int r,g,b; int r,g,b;
...@@ -641,16 +605,12 @@ static void SetYUV( vout_thread_t *p_vout ) ...@@ -641,16 +605,12 @@ static void SetYUV( vout_thread_t *p_vout )
&& r <= RGB_MAX && g <= RGB_MAX && b <= RGB_MAX ) && r <= RGB_MAX && g <= RGB_MAX && b <= RGB_MAX )
{ {
/* this one should never happen unless someone fscked up my code */ /* this one should never happen unless someone fscked up my code */
if(j == 256) { intf_DbgMsg( "sorry, no colors left\n" ); exit( 1 ); } if(j == 256) { intf_ErrMsg( "vout error: no colors left to build palette\n" ); break; }
/* saturate the colors */ /* clip the colors */
SATURATE( r ); red[j] = CLIP( r );
SATURATE( g ); green[j] = CLIP( g );
SATURATE( b ); blue[j] = CLIP( b );
red[j] = r << 8;
green[j] = g << 8;
blue[j] = b << 8;
transp[j] = 0; transp[j] = 0;
/* allocate color */ /* allocate color */
...@@ -1116,10 +1076,11 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_ ...@@ -1116,10 +1076,11 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
int dither11[4] = { 0xc, 0x4, 0xe, 0x6 }; int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
int dither12[4] = { 0x3, 0xb, 0x1, 0x9 }; int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
int dither13[4] = { 0xf, 0x7, 0xd, 0x5 }; int dither13[4] = { 0xf, 0x7, 0xd, 0x5 };
int dither20[4] = { 0x00, 0x10, 0x04, 0x14 };
int dither21[4] = { 0x18, 0x08, 0x1c, 0x0c }; int dither20[4] = { 0x0, 0x10, 0x4, 0x14 };
int dither22[4] = { 0x06, 0x16, 0x02, 0x12 }; int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
int dither23[4] = { 0x1e, 0x0e, 0x1a, 0x0a }; int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
/* other matrices that can be interesting, either for debugging or for effects */ /* other matrices that can be interesting, either for debugging or for effects */
//int dither[4][4] = { { 0, 8, 2, 10 }, { 12, 4, 14, 16 }, { 3, 11, 1, 9}, {15, 7, 13, 5} }; //int dither[4][4] = { { 0, 8, 2, 10 }, { 12, 4, 14, 16 }, { 3, 11, 1, 9}, {15, 7, 13, 5} };
...@@ -1128,6 +1089,7 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_ ...@@ -1128,6 +1089,7 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
//int dither[4][4] = { { 15, 15, 0, 0 }, { 15, 15, 0, 0 }, { 0, 0, 15, 15 }, { 0, 0, 15, 15 } }; //int dither[4][4] = { { 15, 15, 0, 0 }, { 15, 15, 0, 0 }, { 0, 0, 15, 15 }, { 0, 0, 15, 15 } };
//int dither[4][4] = { { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 } }; //int dither[4][4] = { { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 } };
//int dither[4][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } }; //int dither[4][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };
/* /*
* Initialize some values - i_pic_line_width will store the line skip * Initialize some values - i_pic_line_width will store the line skip
*/ */
......
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