X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=tools%2Fquake3%2Fq3map2%2Fimage.c;h=f5c0b1e90f7c4082bad7b6e41785e545087c282a;hb=ed990b29b0790e2a4d798477df8be2965fd80f41;hp=4bf1ec0ee5987442a23daba6423c78769d33a03a;hpb=1483f2b87be32a60ef7e0038f3a893624a3c6639;p=xonotic%2Fnetradiant.git diff --git a/tools/quake3/q3map2/image.c b/tools/quake3/q3map2/image.c index 4bf1ec0e..f5c0b1e9 100644 --- a/tools/quake3/q3map2/image.c +++ b/tools/quake3/q3map2/image.c @@ -36,7 +36,7 @@ /* dependencies */ #include "q3map2.h" - +#include "webp/decode.h" /* ------------------------------------------------------------------------------- @@ -86,6 +86,7 @@ static void LoadDDSBuffer( byte *buffer, int size, byte **pixels, int *width, in DDSDecompress( (ddsBuffer_t*) buffer, *pixels ); } +#ifdef BUILD_CRUNCH /* LoadCRNBuffer loads a crn image into a valid rgba image @@ -106,6 +107,7 @@ void LoadCRNBuffer( byte *buffer, int size, byte **pixels, int *width, int *heig return; } } +#endif // BUILD_CRUNCH /* @@ -228,7 +230,8 @@ static void LoadPNGBuffer( byte *buffer, int size, byte **pixels, int *width, in /* create image pixel buffer */ *width = w; *height = h; - *pixels = safe_malloc( w * h * 4 ); + /* initialize with zeros, this memory area may not be entirely rewritten */ + *pixels = safe_malloc0( w * h * 4 ); /* create row pointers */ rowPointers = safe_malloc( h * sizeof( byte* ) ); @@ -241,7 +244,34 @@ static void LoadPNGBuffer( byte *buffer, int size, byte **pixels, int *width, in /* clean up */ free( rowPointers ); png_destroy_read_struct( &png, &info, &end ); +} + + + +static void LoadWEBPBuffer( byte *buffer, int size, byte **pixels, int *width, int *height ){ + + int image_width; + int image_height; + + if ( !WebPGetInfo( buffer, ( size_t) size, &image_width, &image_height ) ) + { + Sys_FPrintf( SYS_WRN, "WARNING: An error occurred reading WEBP image info\n" ); + return; + } + + /* create image pixel buffer */ + *pixels = safe_malloc( image_width * image_height * 4 ); + *width = image_width; + *height = image_height; + + int out_stride = image_width * 4; + int out_size = image_height * out_stride; + if ( !WebPDecodeRGBAInto( buffer, (size_t) size, *pixels, out_size, out_stride ) ) + { + Sys_FPrintf( SYS_WRN, "WARNING: An error occurred reading WEBP image\n" ); + return; + } } @@ -366,109 +396,129 @@ image_t *ImageLoad( const char *filename ){ return NULL; } - /* strip file extension off name */ - strcpy( name, filename ); - StripExtension( name ); + /* try with extension then without extension + so light.blend will be unfortunately first + tried as light.tga like it always did, but + then, light.blend.tga will be tried as well */ + for ( i = 0; i < 2; i++ ) + { + strcpy( name, filename ); - /* try to find existing image */ - image = ImageFind( name ); - if ( image != NULL ) { - image->refCount++; - return image; - } + if ( i == 0 ) + { + /* strip file extension off name */ + StripExtension( name ); + } - /* none found, so find first non-null image */ - image = NULL; - for ( i = 0; i < MAX_IMAGES; i++ ) - { - if ( images[ i ].name == NULL ) { - image = &images[ i ]; - break; + /* try to find existing image */ + image = ImageFind( name ); + if ( image != NULL ) { + image->refCount++; + return image; } - } - /* too many images? */ - if ( image == NULL ) { - Error( "MAX_IMAGES (%d) exceeded, there are too many image files referenced by the map.", MAX_IMAGES ); - } + /* none found, so find first non-null image */ + image = NULL; + for ( i = 0; i < MAX_IMAGES; i++ ) + { + if ( images[ i ].name == NULL ) { + image = &images[ i ]; + break; + } + } - /* set it up */ - image->name = safe_malloc( strlen( name ) + 1 ); - strcpy( image->name, name ); + /* too many images? */ + if ( image == NULL ) { + Error( "MAX_IMAGES (%d) exceeded, there are too many image files referenced by the map.", MAX_IMAGES ); + } + + /* set it up */ + image->name = safe_malloc( strlen( name ) + 1 ); + strcpy( image->name, name ); + + /* add a dummy extension that can be removed */ + strcat( name, ".tga" ); + + /* Sys_FPrintf( SYS_WRN, "==> Looking for %s\n", name ); */ + + /* attempt to load tga */ + StripExtension( name ); + strcat( name, ".tga" ); + size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 ); + if ( size > 0 ) { + LoadTGABuffer( buffer, buffer + size, &image->pixels, &image->width, &image->height ); + break; + } - /* attempt to load tga */ - StripExtension( name ); - strcat( name, ".tga" ); - size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 ); - if ( size > 0 ) { - LoadTGABuffer( buffer, buffer + size, &image->pixels, &image->width, &image->height ); - } - else - { /* attempt to load png */ StripExtension( name ); strcat( name, ".png" ); size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 ); if ( size > 0 ) { LoadPNGBuffer( buffer, size, &image->pixels, &image->width, &image->height ); + break; } - else - { - /* attempt to load jpg */ - StripExtension( name ); - strcat( name, ".jpg" ); - size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 ); - if ( size > 0 ) { - if ( LoadJPGBuff( buffer, size, &image->pixels, &image->width, &image->height ) == -1 && image->pixels != NULL ) { - // On error, LoadJPGBuff might store a pointer to the error message in image->pixels - Sys_FPrintf( SYS_WRN, "WARNING: LoadJPGBuff: %s\n", (unsigned char*) image->pixels ); - } - alphaHack = qtrue; - } - else - { - /* attempt to load dds */ - StripExtension( name ); - strcat( name, ".dds" ); - size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 ); - if ( size > 0 ) { - LoadDDSBuffer( buffer, size, &image->pixels, &image->width, &image->height ); - - /* debug code */ - #if 1 - { - ddsPF_t pf; - DDSGetInfo( (ddsBuffer_t*) buffer, NULL, NULL, &pf ); - Sys_Printf( "pf = %d\n", pf ); - if ( image->width > 0 ) { - StripExtension( name ); - strcat( name, "_converted.tga" ); - WriteTGA( "C:\\games\\quake3\\baseq3\\textures\\rad\\dds_converted.tga", image->pixels, image->width, image->height ); - } - } - #endif - } - else - { - /* attempt to load ktx */ - StripExtension( name ); - strcat( name, ".ktx" ); - size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 ); - if ( size > 0 ) { - LoadKTXBufferFirstImage( buffer, size, &image->pixels, &image->width, &image->height ); - } - else - { - /* attempt to load crn */ - StripExtension( name ); - strcat( name, ".crn" ); - size = vfsLoadFile( ( const char* ) name, ( void** ) &buffer, 0 ); - if ( size > 0 ) { - LoadCRNBuffer( buffer, size, &image->pixels, &image->width, &image->height ); - } - } - } + + /* attempt to load jpg */ + StripExtension( name ); + strcat( name, ".jpg" ); + size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 ); + if ( size > 0 ) { + if ( LoadJPGBuff( buffer, size, &image->pixels, &image->width, &image->height ) == -1 && image->pixels != NULL ) { + // On error, LoadJPGBuff might store a pointer to the error message in image->pixels + Sys_FPrintf( SYS_WRN, "WARNING: LoadJPGBuff: %s\n", (unsigned char*) image->pixels ); } + alphaHack = qtrue; + break; + } + + /* attempt to load dds */ + StripExtension( name ); + strcat( name, ".dds" ); + size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 ); + + /* also look for .dds image in dds/ prefix like Doom3 or DarkPlaces */ + if ( size <= 0 ) { + char ddsname[ 1024 ]; + strcpy( ddsname, "dds/" ); + strcat( ddsname, image->name ); + StripExtension( ddsname ); + strcat( ddsname, ".dds" ); + size = vfsLoadFile( (const char*) ddsname, (void**) &buffer, 0 ); + } + + if ( size > 0 ) { + LoadDDSBuffer( buffer, size, &image->pixels, &image->width, &image->height ); + break; + } + + /* attempt to load ktx */ + StripExtension( name ); + strcat( name, ".ktx" ); + size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 ); + if ( size > 0 ) { + LoadKTXBufferFirstImage( buffer, size, &image->pixels, &image->width, &image->height ); + break; + } + + #ifdef BUILD_CRUNCH + /* attempt to load crn */ + StripExtension( name ); + strcat( name, ".crn" ); + size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 ); + if ( size > 0 ) { + LoadCRNBuffer( buffer, size, &image->pixels, &image->width, &image->height ); + break; + } + #endif // BUILD_CRUNCH + + /* attempt to load webp */ + StripExtension( name ); + strcat( name, ".webp" ); + size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 ); + if ( size > 0 ) { + LoadWEBPBuffer( buffer, size, &image->pixels, &image->width, &image->height ); + break; } } @@ -477,6 +527,7 @@ image_t *ImageLoad( const char *filename ){ /* make sure everything's kosher */ if ( size <= 0 || image->width <= 0 || image->height <= 0 || image->pixels == NULL ) { + // Sys_FPrintf( SYS_WRN, "WARNING: Image not found: \"%s\"\n", filename ); //% Sys_Printf( "size = %d width = %d height = %d pixels = 0x%08x (%s)\n", //% size, image->width, image->height, image->pixels, name ); free( image->name ); @@ -484,6 +535,9 @@ image_t *ImageLoad( const char *filename ){ return NULL; } + /* tell user which image file is found for the given texture path */ + Sys_FPrintf( SYS_VRB, "Loaded image: \"%s\"\n", name ); + /* set filename */ image->filename = safe_malloc( strlen( name ) + 1 ); strcpy( image->filename, name );