Skip to content
This repository has been archived by the owner on Dec 31, 2020. It is now read-only.

Commit

Permalink
Add support for unpacking arbitrary pixel formats.
Browse files Browse the repository at this point in the history
  • Loading branch information
castano committed Sep 26, 2007
1 parent 3c6cc7c commit c9c7c42
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 7 deletions.
75 changes: 69 additions & 6 deletions src/nvimage/DirectDrawSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,20 +765,83 @@ 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;
uint8 output = c;
// @@ TODO!!!

static uint convert(uint c, uint inbits, uint outbits)
{
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)
{
nvDebugCheck(stream != 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)
Expand Down
2 changes: 1 addition & 1 deletion src/nvimage/ImageIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ bool nv::ImageIO::saveTGA(Stream & s, const Image * img)
tga.head.height = img->height();
if(img->format() == Image::Format_ARGB) {
tga.head.pixel_size = 32;
tga.head.flags = TGA_ORIGIN_UPPER;
tga.head.flags = TGA_ORIGIN_UPPER | TGA_HAS_ALPHA;
}
else {
tga.head.pixel_size = 24;
Expand Down
2 changes: 2 additions & 0 deletions src/nvimage/TgaFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ enum TGAType {
#define TGA_ORIGIN_LOWER 0x00
#define TGA_ORIGIN_UPPER 0x20

#define TGA_HAS_ALPHA 0x0F


/// Tga Header.
struct TgaHeader {
Expand Down
1 change: 1 addition & 0 deletions src/nvimage/nvtt/CompressRGB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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].a, 8, asize) << ashift;

// @@ This is wrong, this pixels overlaps with the previous one!
*(uint *)(dst + x * byteCount) = c;
}
}
Expand Down

0 comments on commit c9c7c42

Please sign in to comment.