Add support for unpacking arbitrary pixel formats.
This commit is contained in:
parent
3c6cc7cfad
commit
c9c7c42d2b
@ -765,12 +765,37 @@ void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8 bitExpand(uint8 c, uint bits)
|
// @@ Move this code to format conversion!!
|
||||||
|
namespace
|
||||||
{
|
{
|
||||||
int shifts = 0;
|
static uint convert(uint c, uint inbits, uint outbits)
|
||||||
uint8 output = c;
|
{
|
||||||
// @@ TODO!!!
|
if (inbits <= outbits)
|
||||||
|
{
|
||||||
|
// truncate
|
||||||
|
return c >> (inbits - outbits);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// bitexpand
|
||||||
|
return (c << (outbits - inbits)) | convert(c, inbits, outbits - inbits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void maskShiftAndSize(uint mask, uint * shift, uint * size)
|
||||||
|
{
|
||||||
|
*shift = 0;
|
||||||
|
while((mask & 1) == 0) {
|
||||||
|
++(*shift);
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*size = 0;
|
||||||
|
while((mask & 1) == 1) {
|
||||||
|
++(*size);
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectDrawSurface::readLinearImage(Image * img)
|
void DirectDrawSurface::readLinearImage(Image * img)
|
||||||
@ -778,7 +803,45 @@ void DirectDrawSurface::readLinearImage(Image * img)
|
|||||||
nvDebugCheck(stream != NULL);
|
nvDebugCheck(stream != NULL);
|
||||||
nvDebugCheck(img != NULL);
|
nvDebugCheck(img != NULL);
|
||||||
|
|
||||||
// @@ Read linear RGB images.
|
const uint w = img->width();
|
||||||
|
const uint h = img->height();
|
||||||
|
|
||||||
|
uint rshift, rsize;
|
||||||
|
maskShiftAndSize(header.pf.rmask, &rshift, &rsize);
|
||||||
|
|
||||||
|
uint gshift, gsize;
|
||||||
|
maskShiftAndSize(header.pf.gmask, &gshift, &gsize);
|
||||||
|
|
||||||
|
uint bshift, bsize;
|
||||||
|
maskShiftAndSize(header.pf.bmask, &bshift, &bsize);
|
||||||
|
|
||||||
|
uint ashift, asize;
|
||||||
|
maskShiftAndSize(header.pf.amask, &ashift, &asize);
|
||||||
|
|
||||||
|
uint byteCount = (header.pf.bitcount + 7) / 8;
|
||||||
|
|
||||||
|
if (header.pf.amask != 0)
|
||||||
|
{
|
||||||
|
img->setFormat(Image::Format_ARGB);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read linear RGB images.
|
||||||
|
for (uint y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
for (uint x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
uint c = 0;
|
||||||
|
stream->serialize(&c, byteCount);
|
||||||
|
|
||||||
|
Color32 pixel(0, 0, 0, 0xFF);
|
||||||
|
pixel.r = convert(c >> rshift, rsize, 8);
|
||||||
|
pixel.g = convert(c >> gshift, gsize, 8);
|
||||||
|
pixel.b = convert(c >> bshift, bsize, 8);
|
||||||
|
pixel.a = convert(c >> ashift, asize, 8);
|
||||||
|
|
||||||
|
img->pixel(x, y) = pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectDrawSurface::readBlockImage(Image * img)
|
void DirectDrawSurface::readBlockImage(Image * img)
|
||||||
|
@ -284,7 +284,7 @@ bool nv::ImageIO::saveTGA(Stream & s, const Image * img)
|
|||||||
tga.head.height = img->height();
|
tga.head.height = img->height();
|
||||||
if(img->format() == Image::Format_ARGB) {
|
if(img->format() == Image::Format_ARGB) {
|
||||||
tga.head.pixel_size = 32;
|
tga.head.pixel_size = 32;
|
||||||
tga.head.flags = TGA_ORIGIN_UPPER;
|
tga.head.flags = TGA_ORIGIN_UPPER | TGA_HAS_ALPHA;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tga.head.pixel_size = 24;
|
tga.head.pixel_size = 24;
|
||||||
|
@ -29,6 +29,8 @@ enum TGAType {
|
|||||||
#define TGA_ORIGIN_LOWER 0x00
|
#define TGA_ORIGIN_LOWER 0x00
|
||||||
#define TGA_ORIGIN_UPPER 0x20
|
#define TGA_ORIGIN_UPPER 0x20
|
||||||
|
|
||||||
|
#define TGA_HAS_ALPHA 0x0F
|
||||||
|
|
||||||
|
|
||||||
/// Tga Header.
|
/// Tga Header.
|
||||||
struct TgaHeader {
|
struct TgaHeader {
|
||||||
|
@ -145,6 +145,7 @@ void nv::compressRGB(const Image * image, const OutputOptions & outputOptions, c
|
|||||||
c |= convert(src[x].b, 8, bsize) << bshift;
|
c |= convert(src[x].b, 8, bsize) << bshift;
|
||||||
c |= convert(src[x].a, 8, asize) << ashift;
|
c |= convert(src[x].a, 8, asize) << ashift;
|
||||||
|
|
||||||
|
// @@ This is wrong, this pixels overlaps with the previous one!
|
||||||
*(uint *)(dst + x * byteCount) = c;
|
*(uint *)(dst + x * byteCount) = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user