mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-15 00:11:55 +07:00
fix and check pvr content size
This commit is contained in:
@@ -69,7 +69,8 @@ namespace
|
|||||||
bool get_dds_format(
|
bool get_dds_format(
|
||||||
const dds_header& hdr,
|
const dds_header& hdr,
|
||||||
image_data_format& out_format,
|
image_data_format& out_format,
|
||||||
u32& out_bytes_per_block) noexcept
|
u32& out_bytes_per_block,
|
||||||
|
v2u& out_block_size) noexcept
|
||||||
{
|
{
|
||||||
if ( math::check_all_flags(hdr.ddspf.dwFlags, ddsf_fourcc) ) {
|
if ( math::check_all_flags(hdr.ddspf.dwFlags, ddsf_fourcc) ) {
|
||||||
switch ( hdr.ddspf.dwFourCC ) {
|
switch ( hdr.ddspf.dwFourCC ) {
|
||||||
@@ -78,14 +79,17 @@ namespace
|
|||||||
? image_data_format::rgba_dxt1
|
? image_data_format::rgba_dxt1
|
||||||
: image_data_format::rgb_dxt1;
|
: image_data_format::rgb_dxt1;
|
||||||
out_bytes_per_block = 8;
|
out_bytes_per_block = 8;
|
||||||
|
out_block_size = v2u(4,4);
|
||||||
break;
|
break;
|
||||||
case fourcc_dxt3:
|
case fourcc_dxt3:
|
||||||
out_format = image_data_format::rgba_dxt3;
|
out_format = image_data_format::rgba_dxt3;
|
||||||
out_bytes_per_block = 16;
|
out_bytes_per_block = 16;
|
||||||
|
out_block_size = v2u(4,4);
|
||||||
break;
|
break;
|
||||||
case fourcc_dxt5:
|
case fourcc_dxt5:
|
||||||
out_format = image_data_format::rgba_dxt5;
|
out_format = image_data_format::rgba_dxt5;
|
||||||
out_bytes_per_block = 16;
|
out_bytes_per_block = 16;
|
||||||
|
out_block_size = v2u(4,4);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -93,12 +97,14 @@ namespace
|
|||||||
} else if ( math::check_all_flags(hdr.ddspf.dwFlags, ddsf_rgba) && (hdr.ddspf.dwRGBBitCount == 32) ) {
|
} else if ( math::check_all_flags(hdr.ddspf.dwFlags, ddsf_rgba) && (hdr.ddspf.dwRGBBitCount == 32) ) {
|
||||||
out_format = image_data_format::rgba8;
|
out_format = image_data_format::rgba8;
|
||||||
out_bytes_per_block = 4;
|
out_bytes_per_block = 4;
|
||||||
|
out_block_size = v2u(1,1);
|
||||||
if ( hdr.ddspf.dwRBitMask == 0x00FF0000 ) {
|
if ( hdr.ddspf.dwRBitMask == 0x00FF0000 ) {
|
||||||
return false; // BGRA format is not supported
|
return false; // BGRA format is not supported
|
||||||
}
|
}
|
||||||
} else if ( math::check_all_flags(hdr.ddspf.dwFlags, ddsf_rgb) && (hdr.ddspf.dwRGBBitCount == 24) ) {
|
} else if ( math::check_all_flags(hdr.ddspf.dwFlags, ddsf_rgb) && (hdr.ddspf.dwRGBBitCount == 24) ) {
|
||||||
out_format = image_data_format::rgb8;
|
out_format = image_data_format::rgb8;
|
||||||
out_bytes_per_block = 3;
|
out_bytes_per_block = 3;
|
||||||
|
out_block_size = v2u(1,1);
|
||||||
if (hdr.ddspf.dwRBitMask == 0x00FF0000) {
|
if (hdr.ddspf.dwRBitMask == 0x00FF0000) {
|
||||||
return false; // BGRA format is not supported
|
return false; // BGRA format is not supported
|
||||||
}
|
}
|
||||||
@@ -107,6 +113,7 @@ namespace
|
|||||||
} else if ( hdr.ddspf.dwRGBBitCount == 8 ) {
|
} else if ( hdr.ddspf.dwRGBBitCount == 8 ) {
|
||||||
out_format = image_data_format::g8;
|
out_format = image_data_format::g8;
|
||||||
out_bytes_per_block = 1;
|
out_bytes_per_block = 1;
|
||||||
|
out_block_size = v2u(1,1);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -123,6 +130,7 @@ namespace e2d::images::impl
|
|||||||
|
|
||||||
const dds_header& hdr = *reinterpret_cast<const dds_header*>(src.data());
|
const dds_header& hdr = *reinterpret_cast<const dds_header*>(src.data());
|
||||||
const u8* content = src.data() + sizeof(dds_header);
|
const u8* content = src.data() + sizeof(dds_header);
|
||||||
|
const std::size_t content_size = static_cast<std::size_t>(src.data() + src.size() - content);
|
||||||
|
|
||||||
if ( math::check_all_flags(hdr.dwCaps2, ddsf_cubemap) ||
|
if ( math::check_all_flags(hdr.dwCaps2, ddsf_cubemap) ||
|
||||||
math::check_all_flags(hdr.dwCaps2, ddsf_volume) ||
|
math::check_all_flags(hdr.dwCaps2, ddsf_volume) ||
|
||||||
@@ -133,22 +141,18 @@ namespace e2d::images::impl
|
|||||||
|
|
||||||
image_data_format format = image_data_format(-1);
|
image_data_format format = image_data_format(-1);
|
||||||
u32 bytes_per_block = 0;
|
u32 bytes_per_block = 0;
|
||||||
if ( !get_dds_format(hdr, format, bytes_per_block) ) {
|
v2u block_size = v2u(1,1);
|
||||||
|
if ( !get_dds_format(hdr, format, bytes_per_block, block_size) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const v2u dimension = v2u(hdr.dwWidth, hdr.dwHeight);
|
const v2u dimension = v2u(hdr.dwWidth, hdr.dwHeight);
|
||||||
std::size_t size;
|
const std::size_t size = bytes_per_block *
|
||||||
|
((dimension.x + block_size.x - 1) / block_size.x) *
|
||||||
|
((dimension.y + block_size.y - 1) / block_size.y);
|
||||||
|
|
||||||
switch ( format ) {
|
if ( content_size != size ) {
|
||||||
case image_data_format::rgb_dxt1:
|
return false;
|
||||||
case image_data_format::rgba_dxt3:
|
|
||||||
case image_data_format::rgba_dxt5:
|
|
||||||
size = ((dimension.x+3)/4) * ((dimension.y+3)/4) * bytes_per_block;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
size = dimension.x * dimension.y * bytes_per_block;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dst = image(dimension, format, buffer(content, size));
|
dst = image(dimension, format, buffer(content, size));
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ namespace e2d::images::impl
|
|||||||
|
|
||||||
const pvr_header& hdr = *reinterpret_cast<const pvr_header*>(src.data());
|
const pvr_header& hdr = *reinterpret_cast<const pvr_header*>(src.data());
|
||||||
const u8* content = src.data() + sizeof(pvr_header) + hdr.metaDataSize;
|
const u8* content = src.data() + sizeof(pvr_header) + hdr.metaDataSize;
|
||||||
|
const std::size_t content_size = static_cast<std::size_t>(src.data() + src.size() - content);
|
||||||
|
|
||||||
if ( hdr.numSurfaces != 1 || hdr.numFaces != 1 || hdr.depth > 1 ) {
|
if ( hdr.numSurfaces != 1 || hdr.numFaces != 1 || hdr.depth > 1 ) {
|
||||||
return false; // cubemap and volume textures are not supported
|
return false; // cubemap and volume textures are not supported
|
||||||
@@ -222,10 +223,14 @@ namespace e2d::images::impl
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
v2u dimension = v2u(hdr.width, hdr.height);
|
const v2u dimension = v2u(hdr.width, hdr.height);
|
||||||
std::size_t size = bytes_per_block *
|
const std::size_t size = bytes_per_block *
|
||||||
(dimension.x + block_size.x - 1) / block_size.x *
|
((dimension.x + block_size.x - 1) / block_size.x) *
|
||||||
(dimension.y + block_size.y - 1) / block_size.y;
|
((dimension.y + block_size.y - 1) / block_size.y);
|
||||||
|
|
||||||
|
if ( content_size != size ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
dst = image(dimension, format, buffer(content, size));
|
dst = image(dimension, format, buffer(content, size));
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user