add support for uncompressed luminance and luminance-alpha dds files

This commit is contained in:
David Rose 2010-04-13 17:19:18 +00:00
parent 5f3cd68162
commit 30155fb72e
2 changed files with 101 additions and 0 deletions

View File

@ -2776,6 +2776,12 @@ do_read_dds(istream &in, const string &filename, bool header_only) {
header.pf.b_mask == 0x000000ff &&
header.pf.a_mask == 0xff000000U) {
func = read_dds_level_rgba8;
} else if (header.pf.r_mask != 0 &&
header.pf.g_mask == 0 &&
header.pf.b_mask == 0) {
func = read_dds_level_luminance_uncompressed;
format = F_luminance_alpha;
}
} else {
// An uncompressed format that doesn't involve alpha.
@ -2789,8 +2795,15 @@ do_read_dds(istream &in, const string &filename, bool header_only) {
header.pf.g_mask == 0x0000ff00 &&
header.pf.b_mask == 0x00ff0000) {
func = read_dds_level_rgb8;
} else if (header.pf.r_mask != 0 &&
header.pf.g_mask == 0 &&
header.pf.b_mask == 0) {
func = read_dds_level_luminance_uncompressed;
format = F_luminance;
}
}
}
do_setup_texture(texture_type, header.width, header.height, header.depth,
@ -5074,6 +5087,91 @@ read_dds_level_generic_uncompressed(Texture *tex, const DDSHeader &header,
return image;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::read_dds_level_luminance_uncompressed
// Access: Private, Static
// Description: Called by read_dds for a DDS file in uncompressed
// luminance or luminance-alpha format.
////////////////////////////////////////////////////////////////////
PTA_uchar Texture::
read_dds_level_luminance_uncompressed(Texture *tex, const DDSHeader &header,
int n, istream &in) {
int x_size = tex->do_get_expected_mipmap_x_size(n);
int y_size = tex->do_get_expected_mipmap_y_size(n);
int pitch = (x_size * header.pf.rgb_bitcount) / 8;
// MS says the pitch can be supplied in the header file and must be
// DWORD aligned, but this appears to apply to level 0 mipmaps only
// (where it almost always will be anyway). Other mipmap levels
// seem to be tightly packed, but there isn't a separate pitch for
// each mipmap level. Weird.
if (n == 0) {
pitch = ((pitch + 3) / 4) * 4;
if (header.dds_flags & DDSD_PITCH) {
pitch = header.pitch;
}
}
int bpp = header.pf.rgb_bitcount / 8;
int skip_bytes = pitch - (bpp * x_size);
nassertr(skip_bytes >= 0, PTA_uchar());
unsigned int r_mask = header.pf.r_mask;
unsigned int a_mask = header.pf.a_mask;
// Determine the number of bits to shift each mask to the right so
// that the lowest on bit is at bit 0.
int r_shift = get_lowest_on_bit(r_mask);
int a_shift = get_lowest_on_bit(a_mask);
// Then determine the scale factor required to raise the highest
// color value to 0xff000000.
unsigned int r_scale = 0;
if (r_mask != 0) {
r_scale = 0xff000000 / (r_mask >> r_shift);
}
unsigned int a_scale = 0;
if (a_mask != 0) {
a_scale = 0xff000000 / (a_mask >> a_shift);
}
bool add_alpha = has_alpha(tex->_format);
size_t size = tex->do_get_expected_ram_mipmap_page_size(n);
size_t row_bytes = x_size * tex->_num_components;
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;
for (int x = 0; x < x_size; ++x) {
// Read a little-endian numeric value of bpp bytes.
unsigned int pixel = 0;
int shift = 0;
for (int bi = 0; bi < bpp; ++bi) {
unsigned int ch = (unsigned char)in.get();
pixel |= (ch << shift);
shift += 8;
}
unsigned int r = (((pixel & r_mask) >> r_shift) * r_scale) >> 24;
// Store the components in the Texture's image data.
store_unscaled_byte(p, r);
if (add_alpha) {
unsigned int a = (((pixel & a_mask) >> a_shift) * a_scale) >> 24;
store_unscaled_byte(p, a);
}
}
nassertr(p <= image.p() + size, PTA_uchar());
for (int bi = 0; bi < skip_bytes; ++bi) {
in.get();
}
}
return image;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::read_dds_level_dxt1
// Access: Private, Static

View File

@ -591,6 +591,9 @@ private:
static PTA_uchar read_dds_level_generic_uncompressed(Texture *tex,
const DDSHeader &header,
int n, istream &in);
static PTA_uchar read_dds_level_luminance_uncompressed(Texture *tex,
const DDSHeader &header,
int n, istream &in);
static PTA_uchar read_dds_level_dxt1(Texture *tex,
const DDSHeader &header,
int n, istream &in);