@@ -90,6 +90,53 @@ int query_DXT_capability( void );
9090#define SOIL_RGBA_S3TC_DXT5 0x83F3
9191typedef void (APIENTRY * P_SOIL_GLCOMPRESSEDTEXIMAGE2DPROC ) (GLenum target , GLint level , GLenum internalformat , GLsizei width , GLsizei height , GLint border , GLsizei imageSize , const GLvoid * data );
9292P_SOIL_GLCOMPRESSEDTEXIMAGE2DPROC soilGlCompressedTexImage2D = NULL ;
93+ typedef const GLubyte * (APIENTRY * P_SOIL_GLGETSTRINGIPROC ) (GLenum name , GLuint index );
94+
95+ /**
96+ https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=727175
97+ "Most SOIL functions crash if OpenGL context is 3.2+ core profile. SOIL calls
98+ glGetString with a value that is no longer valid, and then sends the returned
99+ null pointer to strstr.
100+ This patch checks the OpenGL version at runtime, and uses a glGetString function
101+ that is appropriate and available. It doesn't crash if, for whatever reason,
102+ glGetString returns a null pointer."
103+ - Thanks to Brandon!
104+ **/
105+ static int SOIL_internal_has_OGL_capability (const char * cap )
106+ {
107+ int i ;
108+ GLint num_ext ;
109+ const GLubyte * ext_string ;
110+ int major_version ;
111+
112+ const GLubyte * ver_string = glGetString (GL_VERSION );
113+ if (ver_string )
114+ major_version = atoi ((const char * ) ver_string );
115+ else
116+ major_version = 0 ;
117+
118+ P_SOIL_GLGETSTRINGIPROC soilGlGetStringi =
119+ (P_SOIL_GLGETSTRINGIPROC ) glXGetProcAddressARB ((const GLubyte * ) "glGetStringi" );
120+
121+ if (major_version >= 3 && soilGlGetStringi ) {
122+ // OpenGL 3.0+
123+ glGetIntegerv (GL_NUM_EXTENSIONS , & num_ext );
124+ for (i = 0 ; i < num_ext ; i ++ ) {
125+ ext_string = soilGlGetStringi (GL_EXTENSIONS , i );
126+ if (ext_string && !strcmp ((const char * ) ext_string , cap )) {
127+ return GL_TRUE ;
128+ }
129+ }
130+ }
131+ else {
132+ // OpenGL < 3.0
133+ ext_string = glGetString (GL_EXTENSIONS );
134+ if (ext_string && strstr ((const char * ) ext_string , cap )) {
135+ return GL_TRUE ;
136+ }
137+ }
138+ return GL_FALSE ;
139+ }
93140unsigned int SOIL_direct_load_DDS (
94141 const char * filename ,
95142 unsigned int reuse_texture_ID ,
@@ -1725,7 +1772,7 @@ unsigned int SOIL_direct_load_DDS_from_memory(
17251772 /* do this for each face of the cubemap! */
17261773 for ( cf_target = ogl_target_start ; cf_target <= ogl_target_end ; ++ cf_target )
17271774 {
1728- if ( buffer_index + DDS_full_size <= buffer_length )
1775+ if ( buffer_index + DDS_full_size <= ( unsigned int ) buffer_length )
17291776 {
17301777 unsigned int byte_offset = DDS_main_size ;
17311778 memcpy ( (void * )DDS_data , (const void * )(& buffer [buffer_index ]), DDS_full_size );
@@ -1735,7 +1782,7 @@ unsigned int SOIL_direct_load_DDS_from_memory(
17351782 {
17361783 /* and remember, DXT uncompressed uses BGR(A),
17371784 so swap to RGB(A) for ALL MIPmap levels */
1738- for ( i = 0 ; i < DDS_full_size ; i += block_size )
1785+ for ( i = 0 ; i < ( int ) DDS_full_size ; i += block_size )
17391786 {
17401787 unsigned char temp = DDS_data [i ];
17411788 DDS_data [i ] = DDS_data [i + 2 ];
@@ -1872,29 +1919,25 @@ unsigned int SOIL_direct_load_DDS(
18721919 }
18731920 /* now try to do the loading */
18741921 tex_ID = SOIL_direct_load_DDS_from_memory (
1875- (const unsigned char * const )buffer , buffer_length ,
1922+ (const unsigned char * const )buffer , ( int ) buffer_length ,
18761923 reuse_texture_ID , flags , loading_as_cubemap );
18771924 SOIL_free_image_data ( buffer );
18781925 return tex_ID ;
18791926}
18801927
1928+ // GL_ARB_texture_non_power_of_two is a core feature in OpenGL 2.0
18811929int query_NPOT_capability ( void )
18821930{
18831931 /* check for the capability */
18841932 if ( has_NPOT_capability == SOIL_CAPABILITY_UNKNOWN )
18851933 {
18861934 /* we haven't yet checked for the capability, do so */
1887- if (
1888- (NULL == strstr ( (char const * )glGetString ( GL_EXTENSIONS ),
1889- "GL_ARB_texture_non_power_of_two" ) )
1890- &&
1891- (NULL == strstr ( (char const * )glGetString ( GL_EXTENSIONS ),
1892- "GL_OES_texture_npot" ) )
1893- )
1935+ if (!SOIL_internal_has_OGL_capability ("GL_ARB_texture_non_power_of_two" ))
18941936 {
18951937 /* not there, flag the failure */
18961938 has_NPOT_capability = SOIL_CAPABILITY_NONE ;
1897- } else
1939+ }
1940+ else
18981941 {
18991942 /* it's there! */
19001943 has_NPOT_capability = SOIL_CAPABILITY_PRESENT ;
@@ -1904,26 +1947,21 @@ int query_NPOT_capability( void )
19041947 return has_NPOT_capability ;
19051948}
19061949
1950+ // GL_ARB_texture_rectangle is a core feature in OpenGL 3.1
19071951int query_tex_rectangle_capability ( void )
19081952{
19091953 /* check for the capability */
19101954 if ( has_tex_rectangle_capability == SOIL_CAPABILITY_UNKNOWN )
19111955 {
19121956 /* we haven't yet checked for the capability, do so */
1913- if (
1914- (NULL == strstr ( (char const * )glGetString ( GL_EXTENSIONS ),
1915- "GL_ARB_texture_rectangle" ) )
1916- &&
1917- (NULL == strstr ( (char const * )glGetString ( GL_EXTENSIONS ),
1918- "GL_EXT_texture_rectangle" ) )
1919- &&
1920- (NULL == strstr ( (char const * )glGetString ( GL_EXTENSIONS ),
1921- "GL_NV_texture_rectangle" ) )
1922- )
1957+ if (!SOIL_internal_has_OGL_capability ("GL_ARB_texture_rectangle" ) &&
1958+ !SOIL_internal_has_OGL_capability ("GL_EXT_texture_rectangle" ) &&
1959+ !SOIL_internal_has_OGL_capability ("GL_NV_texture_rectangle" ))
19231960 {
19241961 /* not there, flag the failure */
19251962 has_tex_rectangle_capability = SOIL_CAPABILITY_NONE ;
1926- } else
1963+ }
1964+ else
19271965 {
19281966 /* it's there! */
19291967 has_tex_rectangle_capability = SOIL_CAPABILITY_PRESENT ;
@@ -1933,26 +1971,24 @@ int query_tex_rectangle_capability( void )
19331971 return has_tex_rectangle_capability ;
19341972}
19351973
1974+ // GL_ARB_texture_cube_map is a core feature in OpenGL 1.3
19361975int query_cubemap_capability ( void )
19371976{
19381977 /* check for the capability */
19391978 if ( has_cubemap_capability == SOIL_CAPABILITY_UNKNOWN )
19401979 {
19411980 /* we haven't yet checked for the capability, do so */
1942- if (
1943- (NULL == strstr ( (char const * )glGetString ( GL_EXTENSIONS ),
1944- "GL_ARB_texture_cube_map" ) )
1945- &&
1946- (NULL == strstr ( (char const * )glGetString ( GL_EXTENSIONS ),
1947- "GL_EXT_texture_cube_map" ) )
1981+ if (!SOIL_internal_has_OGL_capability ("GL_ARB_texture_cube_map" ) &&
1982+ !SOIL_internal_has_OGL_capability ("GL_EXT_texture_cube_map" )
19481983 #ifdef GL_ES_VERSION_2_0
19491984 && (0 ) /* GL ES 2.0 supports cubemaps, always enable */
19501985 #endif
19511986 )
19521987 {
19531988 /* not there, flag the failure */
19541989 has_cubemap_capability = SOIL_CAPABILITY_NONE ;
1955- } else
1990+ }
1991+ else
19561992 {
19571993 /* it's there! */
19581994 has_cubemap_capability = SOIL_CAPABILITY_PRESENT ;
@@ -1962,19 +1998,20 @@ int query_cubemap_capability( void )
19621998 return has_cubemap_capability ;
19631999}
19642000
2001+ // GL_EXT_texture_compression_s3tc does not appear to be a core feature in any
2002+ // version of OpenGL up to 4.4
19652003int query_DXT_capability ( void )
19662004{
19672005 /* check for the capability */
19682006 if ( has_DXT_capability == SOIL_CAPABILITY_UNKNOWN )
19692007 {
19702008 /* we haven't yet checked for the capability, do so */
1971- if ( NULL == strstr (
1972- (char const * )glGetString ( GL_EXTENSIONS ),
1973- "GL_EXT_texture_compression_s3tc" ) )
2009+ if (!SOIL_internal_has_OGL_capability ("GL_EXT_texture_compression_s3tc" ))
19742010 {
19752011 /* not there, flag the failure */
19762012 has_DXT_capability = SOIL_CAPABILITY_NONE ;
1977- } else
2013+ }
2014+ else
19782015 {
19792016 /* and find the address of the extension function */
19802017 P_SOIL_GLCOMPRESSEDTEXIMAGE2DPROC ext_addr = NULL ;
0 commit comments