mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
Fix DDS load crash with certain formats; support R16, RG16, R32, RG32
This commit is contained in:
parent
b21e8fdf32
commit
23645cc407
@ -3643,13 +3643,13 @@ do_read_dds(CData *cdata, istream &in, const string &filename, bool header_only)
|
|||||||
header.pf.four_cc == 0x30315844) { // 'DX10'
|
header.pf.four_cc == 0x30315844) { // 'DX10'
|
||||||
// A DirectX 10 style texture, which has an additional header.
|
// A DirectX 10 style texture, which has an additional header.
|
||||||
func = read_dds_level_generic_uncompressed;
|
func = read_dds_level_generic_uncompressed;
|
||||||
unsigned int format = dds.get_uint32();
|
unsigned int dxgi_format = dds.get_uint32();
|
||||||
unsigned int dimension = dds.get_uint32();
|
unsigned int dimension = dds.get_uint32();
|
||||||
unsigned int misc_flag = dds.get_uint32();
|
unsigned int misc_flag = dds.get_uint32();
|
||||||
unsigned int array_size = dds.get_uint32();
|
unsigned int array_size = dds.get_uint32();
|
||||||
/*unsigned int alpha_mode = */dds.get_uint32();
|
/*unsigned int alpha_mode = */dds.get_uint32();
|
||||||
|
|
||||||
switch (format) {
|
switch (dxgi_format) {
|
||||||
case 2: // DXGI_FORMAT_R32G32B32A32_FLOAT
|
case 2: // DXGI_FORMAT_R32G32B32A32_FLOAT
|
||||||
format = F_rgba32;
|
format = F_rgba32;
|
||||||
component_type = T_float;
|
component_type = T_float;
|
||||||
@ -3665,6 +3665,11 @@ do_read_dds(CData *cdata, istream &in, const string &filename, bool header_only)
|
|||||||
component_type = T_unsigned_short;
|
component_type = T_unsigned_short;
|
||||||
func = read_dds_level_abgr16;
|
func = read_dds_level_abgr16;
|
||||||
break;
|
break;
|
||||||
|
case 16: // DXGI_FORMAT_R32G32_FLOAT
|
||||||
|
format = F_rg32;
|
||||||
|
component_type = T_float;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
case 27: // DXGI_FORMAT_R8G8B8A8_TYPELESS
|
case 27: // DXGI_FORMAT_R8G8B8A8_TYPELESS
|
||||||
case 28: // DXGI_FORMAT_R8G8B8A8_UNORM
|
case 28: // DXGI_FORMAT_R8G8B8A8_UNORM
|
||||||
format = F_rgba8;
|
format = F_rgba8;
|
||||||
@ -3688,6 +3693,41 @@ do_read_dds(CData *cdata, istream &in, const string &filename, bool header_only)
|
|||||||
component_type = T_byte;
|
component_type = T_byte;
|
||||||
func = read_dds_level_abgr8;
|
func = read_dds_level_abgr8;
|
||||||
break;
|
break;
|
||||||
|
case 34: // DXGI_FORMAT_R16G16_FLOAT:
|
||||||
|
format = F_rg16;
|
||||||
|
component_type = T_half_float;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
|
case 35: // DXGI_FORMAT_R16G16_UNORM:
|
||||||
|
format = F_rg16;
|
||||||
|
component_type = T_unsigned_short;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
|
case 37: // DXGI_FORMAT_R16G16_SNORM:
|
||||||
|
format = F_rg16;
|
||||||
|
component_type = T_short;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
|
case 40: // DXGI_FORMAT_D32_FLOAT
|
||||||
|
format = F_depth_component32;
|
||||||
|
component_type = T_float;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
|
case 41: // DXGI_FORMAT_R32_FLOAT
|
||||||
|
format = F_r32;
|
||||||
|
component_type = T_float;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
|
case 42: // DXGI_FORMAT_R32_UINT
|
||||||
|
format = F_r32i;
|
||||||
|
component_type = T_unsigned_int;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
|
case 43: // DXGI_FORMAT_R32_SINT
|
||||||
|
format = F_r32i;
|
||||||
|
component_type = T_int;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
case 48: // DXGI_FORMAT_R8G8_TYPELESS
|
case 48: // DXGI_FORMAT_R8G8_TYPELESS
|
||||||
case 49: // DXGI_FORMAT_R8G8_UNORM
|
case 49: // DXGI_FORMAT_R8G8_UNORM
|
||||||
format = F_rg;
|
format = F_rg;
|
||||||
@ -3703,6 +3743,36 @@ do_read_dds(CData *cdata, istream &in, const string &filename, bool header_only)
|
|||||||
format = F_rg8i;
|
format = F_rg8i;
|
||||||
component_type = T_byte;
|
component_type = T_byte;
|
||||||
break;
|
break;
|
||||||
|
case 54: // DXGI_FORMAT_R16_FLOAT:
|
||||||
|
format = F_r16;
|
||||||
|
component_type = T_half_float;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
|
case 55: // DXGI_FORMAT_D16_UNORM:
|
||||||
|
format = F_depth_component16;
|
||||||
|
component_type = T_unsigned_short;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
|
case 56: // DXGI_FORMAT_R16_UNORM:
|
||||||
|
format = F_r16;
|
||||||
|
component_type = T_unsigned_short;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
|
case 57: // DXGI_FORMAT_R16_UINT:
|
||||||
|
format = F_r16i;
|
||||||
|
component_type = T_unsigned_short;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
|
case 58: // DXGI_FORMAT_R16_SNORM:
|
||||||
|
format = F_r16;
|
||||||
|
component_type = T_short;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
|
case 59: // DXGI_FORMAT_R16_SINT:
|
||||||
|
format = F_r16i;
|
||||||
|
component_type = T_short;
|
||||||
|
func = read_dds_level_raw;
|
||||||
|
break;
|
||||||
case 60: // DXGI_FORMAT_R8_TYPELESS
|
case 60: // DXGI_FORMAT_R8_TYPELESS
|
||||||
case 61: // DXGI_FORMAT_R8_UNORM
|
case 61: // DXGI_FORMAT_R8_UNORM
|
||||||
format = F_red;
|
format = F_red;
|
||||||
@ -3760,7 +3830,6 @@ do_read_dds(CData *cdata, istream &in, const string &filename, bool header_only)
|
|||||||
compression = CM_rgtc;
|
compression = CM_rgtc;
|
||||||
func = read_dds_level_bc4;
|
func = read_dds_level_bc4;
|
||||||
break;
|
break;
|
||||||
break;
|
|
||||||
case 82: // DXGI_FORMAT_BC5_TYPELESS
|
case 82: // DXGI_FORMAT_BC5_TYPELESS
|
||||||
case 83: // DXGI_FORMAT_BC5_UNORM
|
case 83: // DXGI_FORMAT_BC5_UNORM
|
||||||
format = F_rg;
|
format = F_rg;
|
||||||
@ -3786,7 +3855,7 @@ do_read_dds(CData *cdata, istream &in, const string &filename, bool header_only)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
gobj_cat.error()
|
gobj_cat.error()
|
||||||
<< filename << ": unsupported DXGI format " << format << ".\n";
|
<< filename << ": unsupported DXGI format " << dxgi_format << ".\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8264,6 +8333,7 @@ read_dds_level_abgr32(Texture *tex, CData *cdata, const DDSHeader &header, int n
|
|||||||
|
|
||||||
size_t size = tex->do_get_expected_ram_mipmap_page_size(cdata, n);
|
size_t size = tex->do_get_expected_ram_mipmap_page_size(cdata, n);
|
||||||
size_t row_bytes = x_size * 16;
|
size_t row_bytes = x_size * 16;
|
||||||
|
nassertr(row_bytes * y_size == size, PTA_uchar());
|
||||||
PTA_uchar image = PTA_uchar::empty_array(size);
|
PTA_uchar image = PTA_uchar::empty_array(size);
|
||||||
for (int y = y_size - 1; y >= 0; --y) {
|
for (int y = y_size - 1; y >= 0; --y) {
|
||||||
unsigned char *p = image.p() + y * row_bytes;
|
unsigned char *p = image.p() + y * row_bytes;
|
||||||
@ -8280,6 +8350,26 @@ read_dds_level_abgr32(Texture *tex, CData *cdata, const DDSHeader &header, int n
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by read_dds for a DDS file that needs no transformations applied.
|
||||||
|
*/
|
||||||
|
PTA_uchar Texture::
|
||||||
|
read_dds_level_raw(Texture *tex, CData *cdata, const DDSHeader &header, int n, istream &in) {
|
||||||
|
int x_size = tex->do_get_expected_mipmap_x_size(cdata, n);
|
||||||
|
int y_size = tex->do_get_expected_mipmap_y_size(cdata, n);
|
||||||
|
|
||||||
|
size_t size = tex->do_get_expected_ram_mipmap_page_size(cdata, n);
|
||||||
|
size_t row_bytes = x_size * cdata->_num_components * cdata->_component_width;
|
||||||
|
nassertr(row_bytes * y_size == size, PTA_uchar());
|
||||||
|
PTA_uchar image = PTA_uchar::empty_array(size);
|
||||||
|
for (int y = y_size - 1; y >= 0; --y) {
|
||||||
|
unsigned char *p = image.p() + y * row_bytes;
|
||||||
|
in.read((char *)p, row_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by read_dds for a DDS file whose format isn't one we've specifically
|
* Called by read_dds for a DDS file whose format isn't one we've specifically
|
||||||
* optimized.
|
* optimized.
|
||||||
|
@ -817,6 +817,8 @@ private:
|
|||||||
int n, istream &in);
|
int n, istream &in);
|
||||||
static PTA_uchar read_dds_level_abgr32(Texture *tex, CData *cdata, const DDSHeader &header,
|
static PTA_uchar read_dds_level_abgr32(Texture *tex, CData *cdata, const DDSHeader &header,
|
||||||
int n, istream &in);
|
int n, istream &in);
|
||||||
|
static PTA_uchar read_dds_level_raw(Texture *tex, CData *cdata, const DDSHeader &header,
|
||||||
|
int n, istream &in);
|
||||||
static PTA_uchar read_dds_level_generic_uncompressed(Texture *tex, CData *cdata,
|
static PTA_uchar read_dds_level_generic_uncompressed(Texture *tex, CData *cdata,
|
||||||
const DDSHeader &header,
|
const DDSHeader &header,
|
||||||
int n, istream &in);
|
int n, istream &in);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user