X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=tools%2Fquake3%2Fq3map2%2Fimage.c;h=e5f97a40c1dbc8d4d71531bbc237926ef033020f;hp=5ab1d48b1c1a4799b295564851401d751a93a6e0;hb=993436857c367edb700c5910604d89ec124e87c1;hpb=dac8329952745dbb494bad1c301e44bab05ec0db diff --git a/tools/quake3/q3map2/image.c b/tools/quake3/q3map2/image.c index 5ab1d48b..e5f97a40 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" /* ------------------------------------------------------------------------------- @@ -67,13 +67,13 @@ static void LoadDDSBuffer( byte *buffer, int size, byte **pixels, int *width, in /* get dds info */ if ( DDSGetInfo( (ddsBuffer_t*) buffer, &w, &h, &pf ) ) { - Sys_Printf( "WARNING: Invalid DDS texture\n" ); + Sys_FPrintf( SYS_WRN, "WARNING: Invalid DDS texture\n" ); return; } /* only certain types of dds textures are supported */ if ( pf != DDS_PF_ARGB8888 && pf != DDS_PF_DXT1 && pf != DDS_PF_DXT3 && pf != DDS_PF_DXT5 ) { - Sys_Printf( "WARNING: Only DDS texture formats ARGB8888, DXT1, DXT3, and DXT5 are supported (%d)\n", pf ); + Sys_FPrintf( SYS_WRN, "WARNING: Only DDS texture formats ARGB8888, DXT1, DXT3, and DXT5 are supported (%d)\n", pf ); return; } @@ -86,6 +86,28 @@ 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 +*/ +void LoadCRNBuffer( byte *buffer, int size, byte **pixels, int *width, int *height) { + /* dummy check */ + if ( buffer == NULL || size <= 0 || pixels == NULL || width == NULL || height == NULL ) { + return; + } + if ( !GetCRNImageSize( buffer, size, width, height ) ) { + Sys_FPrintf( SYS_WRN, "WARNING: Error getting crn imag dimensions.\n");; + return; + } + int outBufSize = *width * *height * 4; + *pixels = safe_malloc( outBufSize ); + if ( !ConvertCRNtoRGBA( buffer, size, outBufSize, *pixels) ) { + Sys_FPrintf( SYS_WRN, "WARNING: Error decoding crn image.\n", 0 ); + return; + } +} +#endif // BUILD_CRUNCH /* @@ -123,7 +145,6 @@ static void LoadPNGBuffer( byte *buffer, int size, byte **pixels, int *width, in png_struct *png; png_info *info, *end; pngBuffer_t pb; - //pngBuffer_t *pb = (pngBuffer_t*) png_get_io_ptr( png ); int bitDepth, colorType; png_uint_32 w, h, i; byte **rowPointers; @@ -140,27 +161,27 @@ static void LoadPNGBuffer( byte *buffer, int size, byte **pixels, int *width, in /* determine if this is a png file */ if ( png_sig_cmp( buffer, 0, 8 ) != 0 ) { - Sys_Printf( "WARNING: Invalid PNG file\n" ); + Sys_FPrintf( SYS_WRN, "WARNING: Invalid PNG file\n" ); return; } /* create png structs */ png = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if ( png == NULL ) { - Sys_Printf( "WARNING: Unable to create PNG read struct\n" ); + Sys_FPrintf( SYS_WRN, "WARNING: Unable to create PNG read struct\n" ); return; } info = png_create_info_struct( png ); if ( info == NULL ) { - Sys_Printf( "WARNING: Unable to create PNG info struct\n" ); + Sys_FPrintf( SYS_WRN, "WARNING: Unable to create PNG info struct\n" ); png_destroy_read_struct( &png, NULL, NULL ); return; } end = png_create_info_struct( png ); if ( end == NULL ) { - Sys_Printf( "WARNING: Unable to create PNG end info struct\n" ); + Sys_FPrintf( SYS_WRN, "WARNING: Unable to create PNG end info struct\n" ); png_destroy_read_struct( &png, &info, NULL ); return; } @@ -170,11 +191,10 @@ static void LoadPNGBuffer( byte *buffer, int size, byte **pixels, int *width, in pb.size = size; pb.offset = 0; png_set_read_fn( png, &pb, PNGReadData ); - //png->io_ptr = &pb; /* hack! */ /* set error longjmp */ if ( setjmp( png_jmpbuf(png) ) ) { - Sys_Printf( "WARNING: An error occurred reading PNG image\n" ); + Sys_FPrintf( SYS_WRN, "WARNING: An error occurred reading PNG image\n" ); png_destroy_read_struct( &png, &info, &end ); return; } @@ -228,6 +248,34 @@ static void LoadPNGBuffer( byte *buffer, int size, byte **pixels, int *width, in +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; + } +} + + + /* ImageInit() implicitly called by every function to set up image list @@ -384,55 +432,71 @@ image_t *ImageLoad( const char *filename ){ size = vfsLoadFile( (const char*) name, (void**) &buffer, 0 ); if ( size > 0 ) { LoadTGABuffer( buffer, buffer + size, &image->pixels, &image->width, &image->height ); + goto image_load_success; } - 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 ); - } - 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 ) { - Sys_Printf( "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 - } - } + + /* 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 ); + goto image_load_success; + } + + /* 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; + goto image_load_success; + } + + /* 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 ); + goto image_load_success; } + /* 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 ); + goto image_load_success; + } + + #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 ); + goto image_load_success; + } + #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 ); + goto image_load_success; + } + + image_load_success: + /* free file buffer */ free( buffer ); @@ -460,15 +524,19 @@ image_t *ImageLoad( const char *filename ){ if ( size > 0 ) { unsigned char *pixels; int width, height; - if ( LoadJPGBuff( buffer, size, &pixels, &width, &height ) == -1 && pixels != NULL ) { - Sys_Printf( "WARNING: LoadJPGBuff: %s\n", (unsigned char*) image->pixels ); - } - if ( pixels && width == image->width && height == image->height ) { - int i; - for ( i = 0; i < width * height; ++i ) - image->pixels[4 * i + 3] = pixels[4 * i + 2]; // copy alpha from blue channel + if ( LoadJPGBuff( buffer, size, &pixels, &width, &height ) == -1 ) { + if (pixels) { + // On error, LoadJPGBuff might store a pointer to the error message in pixels + Sys_FPrintf( SYS_WRN, "WARNING: LoadJPGBuff %s %s\n", name, (unsigned char*) pixels ); + } + } else { + if ( width == image->width && height == image->height ) { + int i; + for ( i = 0; i < width * height; ++i ) + image->pixels[4 * i + 3] = pixels[4 * i + 2]; // copy alpha from blue channel + } + free( pixels ); } - free( pixels ); free( buffer ); } }