mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-10 06:31:48 +00:00
image read/write errors print warnings instead of causing drop errors
This commit is contained in:
parent
2389b5db39
commit
0ee2a50e90
2 changed files with 64 additions and 13 deletions
|
@ -35,6 +35,10 @@ add: /waitms <milliseconds> to delay command executions by the specified number
|
||||||
add: r_alphaToCoverageMipBoost <0.0 to 0.5> (default: 0.125) boosts the alpha value of higher mip levels
|
add: r_alphaToCoverageMipBoost <0.0 to 0.5> (default: 0.125) boosts the alpha value of higher mip levels
|
||||||
with A2C enabled, it prevents alpha-tested surfaces from fading (too much) in the distance
|
with A2C enabled, it prevents alpha-tested surfaces from fading (too much) in the distance
|
||||||
|
|
||||||
|
chg: image load/save errors now print warnings instead of triggering drop errors
|
||||||
|
|
||||||
|
chg: the maximum texture resolution of 2048 is now enforced in all image loads
|
||||||
|
|
||||||
chg: updated icon courtesy of deft
|
chg: updated icon courtesy of deft
|
||||||
|
|
||||||
chg: r_showtris/r_shownormals <bitmask> (default: 0) draws wireframe triangles/vertex normals
|
chg: r_showtris/r_shownormals <bitmask> (default: 0) draws wireframe triangles/vertex normals
|
||||||
|
|
|
@ -464,6 +464,28 @@ image_t* R_CreateImage( const char* name, byte* pic, int width, int height, text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static qbool ValidateImageResolution( int w, int h, const char* fileName )
|
||||||
|
{
|
||||||
|
const int dim[2] = { w, h };
|
||||||
|
const char* const dimNames[2] = { "width", "height" };
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
if (dim[i] <= 0) {
|
||||||
|
ri.Printf( PRINT_WARNING, "%s: %s (%d) is too small\n", fileName, dimNames[i], dim[i] );
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dim[i] > MAX_TEXTURE_SIZE) {
|
||||||
|
ri.Printf( PRINT_WARNING, "%s: %s (%d) is too large (max. %d)\n",
|
||||||
|
fileName, dimNames[i], dim[i], MAX_TEXTURE_SIZE );
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return qtrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static qbool LoadTGA( const char* fileName, byte* buffer, int len, byte** pic, int* w, int* h, textureFormat_t* format )
|
static qbool LoadTGA( const char* fileName, byte* buffer, int len, byte** pic, int* w, int* h, textureFormat_t* format )
|
||||||
{
|
{
|
||||||
*pic = NULL;
|
*pic = NULL;
|
||||||
|
@ -485,25 +507,37 @@ static qbool LoadTGA( const char* fileName, byte* buffer, int len, byte** pic, i
|
||||||
if (targa_header.id_length != 0)
|
if (targa_header.id_length != 0)
|
||||||
p += targa_header.id_length;
|
p += targa_header.id_length;
|
||||||
|
|
||||||
if (targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3)
|
#define ERROR(Msg, ...) ri.Printf(PRINT_WARNING, Msg "\n", ##__VA_ARGS__); return qfalse
|
||||||
ri.Error( ERR_DROP, "LoadTGA %s: Only type 2, 10 and 3 images supported\n", fileName );
|
|
||||||
|
|
||||||
if (targa_header.colormap_type)
|
if (targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3) {
|
||||||
ri.Error( ERR_DROP, "LoadTGA %s: Colormaps are not supported\n", fileName );
|
ERROR( "LoadTGA %s: Only type 2, 10 and 3 images supported", fileName );
|
||||||
|
}
|
||||||
|
|
||||||
if (targa_header.image_type != 3 && targa_header.pixel_size != 32 && targa_header.pixel_size != 24)
|
if (targa_header.colormap_type) {
|
||||||
ri.Error( ERR_DROP, "LoadTGA %s: Only 32-bit and 24-bit color images are supported\n", fileName );
|
ERROR( "LoadTGA %s: Colormaps are not supported", fileName );
|
||||||
|
}
|
||||||
|
|
||||||
if (targa_header.image_type == 3 && targa_header.pixel_size != 8)
|
if (targa_header.image_type != 3 && targa_header.pixel_size != 32 && targa_header.pixel_size != 24) {
|
||||||
ri.Error( ERR_DROP, "LoadTGA %s: Only 8-bit greyscale images are supported\n", fileName );
|
ERROR( "LoadTGA %s: Only 32-bit and 24-bit color images are supported", fileName );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targa_header.image_type == 3 && targa_header.pixel_size != 8) {
|
||||||
|
ERROR( "LoadTGA %s: Only 8-bit greyscale images are supported", fileName );
|
||||||
|
}
|
||||||
|
|
||||||
const int bpp = targa_header.pixel_size / 8;
|
const int bpp = targa_header.pixel_size / 8;
|
||||||
const int width = targa_header.width;
|
const int width = targa_header.width;
|
||||||
const int height = targa_header.height;
|
const int height = targa_header.height;
|
||||||
const unsigned numBytes = width * height * 4;
|
const unsigned numBytes = width * height * 4;
|
||||||
|
|
||||||
if (width <= 0 || height <= 0 || numBytes > 0x7FFFFFFF || numBytes / (width * 4) != height)
|
if (!ValidateImageResolution( width, height, fileName ))
|
||||||
ri.Error( ERR_DROP, "LoadTGA %s: Invalid image size\n", fileName );
|
return qfalse;
|
||||||
|
|
||||||
|
if (numBytes / (width * 4) != height) {
|
||||||
|
ERROR( "LoadTGA %s: Invalid image size", fileName );
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ERROR
|
||||||
|
|
||||||
*pic = (byte*)ri.Malloc( numBytes );
|
*pic = (byte*)ri.Malloc( numBytes );
|
||||||
*w = width;
|
*w = width;
|
||||||
|
@ -512,7 +546,7 @@ static qbool LoadTGA( const char* fileName, byte* buffer, int len, byte** pic, i
|
||||||
|
|
||||||
#define UNMUNGE_PIXEL { dst[2] = pixel[0]; dst[1] = pixel[1]; dst[0] = pixel[2]; dst[3] = pixel[3]; dst += 4; }
|
#define UNMUNGE_PIXEL { dst[2] = pixel[0]; dst[1] = pixel[1]; dst[0] = pixel[2]; dst[3] = pixel[3]; dst += 4; }
|
||||||
#define WRAP_ROW if ((++x == width) && y--) { x = 0; dst = *pic + y*width*4; }
|
#define WRAP_ROW if ((++x == width) && y--) { x = 0; dst = *pic + y*width*4; }
|
||||||
#define RANGE_CHECK(Bytes) if (p + (Bytes) > pEnd) { ri.Error( ERR_DROP, "LoadTGA %s: Truncated file\n", fileName ); }
|
#define RANGE_CHECK(Bytes) if (p + (Bytes) > pEnd) { ri.Printf( PRINT_WARNING, "LoadTGA %s: Truncated file\n", fileName ); ri.Free( *pic ); *pic = NULL; return qfalse; }
|
||||||
|
|
||||||
// uncompressed luminance
|
// uncompressed luminance
|
||||||
if (targa_header.image_type == 3) {
|
if (targa_header.image_type == 3) {
|
||||||
|
@ -657,8 +691,16 @@ static qbool LoadJPG( const char* fileName, byte* buffer, int len, byte** pic, i
|
||||||
jpeg_error_mgr jerr;
|
jpeg_error_mgr jerr;
|
||||||
engineJPEGInfo_t extra;
|
engineJPEGInfo_t extra;
|
||||||
|
|
||||||
if (setjmp(extra.jumpBuffer))
|
*pic = NULL;
|
||||||
|
|
||||||
|
if (setjmp( extra.jumpBuffer )) {
|
||||||
|
jpeg_destroy_decompress( &cinfo );
|
||||||
|
if (*pic != NULL) {
|
||||||
|
ri.Free( *pic );
|
||||||
|
*pic = NULL;
|
||||||
|
}
|
||||||
return qfalse;
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
extra.load = qtrue;
|
extra.load = qtrue;
|
||||||
extra.fileName = fileName;
|
extra.fileName = fileName;
|
||||||
|
@ -672,6 +714,9 @@ static qbool LoadJPG( const char* fileName, byte* buffer, int len, byte** pic, i
|
||||||
|
|
||||||
jpeg_read_header( &cinfo, TRUE );
|
jpeg_read_header( &cinfo, TRUE );
|
||||||
jpeg_start_decompress( &cinfo );
|
jpeg_start_decompress( &cinfo );
|
||||||
|
if (!ValidateImageResolution( cinfo.output_width, cinfo.output_height, fileName )) {
|
||||||
|
longjmp( extra.jumpBuffer, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
const unsigned numBytes = cinfo.output_width * cinfo.output_height * 4;
|
const unsigned numBytes = cinfo.output_width * cinfo.output_height * 4;
|
||||||
*pic = (byte*)ri.Malloc(numBytes);
|
*pic = (byte*)ri.Malloc(numBytes);
|
||||||
|
@ -712,8 +757,10 @@ int SaveJPGToBuffer( byte* out, int quality, int image_width, int image_height,
|
||||||
jpeg_error_mgr jerr;
|
jpeg_error_mgr jerr;
|
||||||
engineJPEGInfo_t extra;
|
engineJPEGInfo_t extra;
|
||||||
|
|
||||||
if (setjmp(extra.jumpBuffer))
|
if (setjmp( extra.jumpBuffer )) {
|
||||||
|
jpeg_destroy_compress( &cinfo );
|
||||||
return qfalse;
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
extra.load = qfalse;
|
extra.load = qfalse;
|
||||||
extra.fileName = fileName;
|
extra.fileName = fileName;
|
||||||
|
|
Loading…
Reference in a new issue