Skip to content

Commit

Permalink
GRAPHICS: Convert our old PixelFormat to Ogre's
Browse files Browse the repository at this point in the history
  • Loading branch information
DrMcCoy committed Mar 21, 2014
1 parent bbd5009 commit bc08795
Show file tree
Hide file tree
Showing 13 changed files with 139 additions and 259 deletions.
80 changes: 13 additions & 67 deletions src/graphics/images/dds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,22 +148,13 @@ void DDS::readBioWareHeader(Common::SeekableReadStream &dds) {
if (!IsPower2(width) || !IsPower2(height))
throw Common::Exception("Width and height must be powers of 2");

// Always compressed
_compressed = true;

// Check which compression
uint32 bpp = dds.readUint32LE();
if (bpp == 3) {
_hasAlpha = false;
_format = kPixelFormatBGR;
_formatRaw = kPixelFormatDXT1;
_dataType = kPixelDataType8;
} else if (bpp == 4) {
_hasAlpha = true;
_format = kPixelFormatBGRA;
_formatRaw = kPixelFormatDXT5;
_dataType = kPixelDataType8;
} else
if (bpp == 3)
_format = kPixelFormatDXT1;
else if (bpp == 4)
_format = kPixelFormatDXT5;
else
throw Common::Exception("Unsupported bytes per pixel value (%d)", bpp);

// Sanity check for the image data size
Expand Down Expand Up @@ -203,24 +194,7 @@ void DDS::readBioWareHeader(Common::SeekableReadStream &dds) {
}

void DDS::setSize(MipMap &mipMap) {
// Depending on the pixel format, set the image data size in bytes

if (_formatRaw == kPixelFormatDXT1) {
mipMap.size = ((mipMap.width + 3) / 4) * ((mipMap.height + 3) / 4) * 8;
} else if (_formatRaw == kPixelFormatDXT3) {
mipMap.size = ((mipMap.width + 3) / 4) * ((mipMap.height + 3) / 4) * 16;
} else if (_formatRaw == kPixelFormatDXT5) {
mipMap.size = ((mipMap.width + 3) / 4) * ((mipMap.height + 3) / 4) * 16;
} else if (_formatRaw == kPixelFormatRGBA8) {
mipMap.size = mipMap.width * mipMap.height * 4;
} else if (_formatRaw == kPixelFormatRGB8) {
mipMap.size = mipMap.width * mipMap.height * 3;
} else if (_formatRaw == kPixelFormatRGB5A1) {
mipMap.size = mipMap.width * mipMap.height * 2;
} else if (_formatRaw == kPixelFormatRGB5) {
mipMap.size = mipMap.width * mipMap.height * 2;
} else
mipMap.size = 0;
mipMap.size = calculateSizeInBytes(mipMap.width, mipMap.height, _format);
}

void DDS::readData(Common::SeekableReadStream &dds) {
Expand All @@ -238,65 +212,37 @@ void DDS::detectFormat(const DDSPixelFormat &format) {
// Big, ugly big pixel format description => format mapping

if ((format.flags & kPixelFlagsHasFourCC) && (format.fourCC == kDXT1ID)) {
_compressed = true;
_hasAlpha = false;
_format = kPixelFormatBGR;
_formatRaw = kPixelFormatDXT1;
_dataType = kPixelDataType8;
_format = kPixelFormatDXT1;
} else if ((format.flags & kPixelFlagsHasFourCC) && (format.fourCC == kDXT3ID)) {
_compressed = true;
_hasAlpha = true;
_format = kPixelFormatBGRA;
_formatRaw = kPixelFormatDXT3;
_dataType = kPixelDataType8;
_format = kPixelFormatDXT3;
} else if ((format.flags & kPixelFlagsHasFourCC) && (format.fourCC == kDXT5ID)) {
_compressed = true;
_hasAlpha = true;
_format = kPixelFormatBGRA;
_formatRaw = kPixelFormatDXT5;
_dataType = kPixelDataType8;
_format = kPixelFormatDXT5;
} else if ((format.flags & kPixelFlagsIsRGB) && (format.flags & kPixelFlagsHasAlpha) &&
(format.bitCount == 32) &&
(format.rBitMask == 0x00FF0000) && (format.gBitMask == 0x0000FF00) &&
(format.bBitMask == 0x000000FF) && (format.aBitMask == 0xFF000000)) {
_compressed = false;
_hasAlpha = true;
_format = kPixelFormatBGRA;
_formatRaw = kPixelFormatRGBA8;
_dataType = kPixelDataType8;
_format = kPixelFormatB8G8R8A8;
} else if ((format.flags & kPixelFlagsIsRGB) && !(format.flags & kPixelFlagsHasAlpha) &&
(format.bitCount == 24) &&
(format.rBitMask == 0x00FF0000) && (format.gBitMask == 0x0000FF00) &&
(format.bBitMask == 0x000000FF)) {
_compressed = false;
_hasAlpha = false;
_format = kPixelFormatBGR;
_formatRaw = kPixelFormatRGB8;
_dataType = kPixelDataType8;
_format = kPixelFormatB8G8R8;

warning("Found untested DDS RGB8 data");

} else if ((format.flags & kPixelFlagsIsRGB) && (format.flags & kPixelFlagsHasAlpha) &&
(format.bitCount == 16) &&
(format.rBitMask == 0x00007C00) && (format.gBitMask == 0x000003E0) &&
(format.bBitMask == 0x0000001F) && (format.aBitMask == 0x00008000)) {
_compressed = false;
_hasAlpha = true;
_format = kPixelFormatBGRA;
_formatRaw = kPixelFormatRGB5A1;
_dataType = kPixelDataType1555;
_format = kPixelFormatA1R5G5B5;

warning("Found untested DDS RGB5A1 data");

} else if ((format.flags & kPixelFlagsIsRGB) && !(format.flags & kPixelFlagsHasAlpha) &&
(format.bitCount == 16) &&
(format.rBitMask == 0x0000F800) && (format.gBitMask == 0x000007E0) &&
(format.bBitMask == 0x0000001F)) {
_compressed = false;
_hasAlpha = false;
_format = kPixelFormatBGR;
_formatRaw = kPixelFormatRGB5;
_dataType = kPixelDataType565;
_format = kPixelFormatR5G6B5;

warning("Found untested DDS RGB5 data");

Expand Down
77 changes: 54 additions & 23 deletions src/graphics/images/decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ void ImageDecoder::MipMap::swap(MipMap &right) {
}


ImageDecoder::ImageDecoder() : _compressed(false), _hasAlpha(false),
_format(kPixelFormatBGRA), _formatRaw(kPixelFormatRGBA8), _dataType(kPixelDataType8) {

ImageDecoder::ImageDecoder() : _format(kPixelFormatNone) {
}

ImageDecoder::~ImageDecoder() {
Expand All @@ -69,25 +67,17 @@ Common::SeekableReadStream *ImageDecoder::getTXI() const {
}

bool ImageDecoder::isCompressed() const {
return _compressed;
return isCompressed(_format);
}

bool ImageDecoder::hasAlpha() const {
return _hasAlpha;
return hasAlpha(_format);
}

PixelFormat ImageDecoder::getFormat() const {
return _format;
}

PixelFormatRaw ImageDecoder::getFormatRaw() const {
return _formatRaw;
}

PixelDataType ImageDecoder::getDataType() const {
return _dataType;
}

uint32 ImageDecoder::getMipMapCount() const {
return _mipMaps.size();
}
Expand All @@ -98,7 +88,7 @@ const ImageDecoder::MipMap &ImageDecoder::getMipMap(uint32 mipMap) const {
return *_mipMaps[mipMap];
}

void ImageDecoder::decompress(MipMap &out, const MipMap &in, PixelFormatRaw format) {
void ImageDecoder::decompress(MipMap &out, const MipMap &in, PixelFormat format) {
if ((format != kPixelFormatDXT1) &&
(format != kPixelFormatDXT3) &&
(format != kPixelFormatDXT5))
Expand All @@ -122,37 +112,78 @@ void ImageDecoder::decompress(MipMap &out, const MipMap &in, PixelFormatRaw form
}

void ImageDecoder::decompress() {
if (!_compressed)
if (!isCompressed())
return;

for (std::vector<MipMap *>::iterator m = _mipMaps.begin(); m != _mipMaps.end(); ++m) {
MipMap decompressed;

decompress(decompressed, **m, _formatRaw);
decompress(decompressed, **m, _format);

decompressed.swap(**m);
}

_format = kPixelFormatRGBA;
_formatRaw = kPixelFormatRGBA8;
_dataType = kPixelDataType8;
_compressed = false;
_format = kPixelFormatR8G8B8A8;
}

bool ImageDecoder::dumpTGA(const Common::UString &fileName) const {
if (_mipMaps.size() < 1)
return false;

if (!_compressed) {
if (!isCompressed()) {
Graphics::dumpTGA(fileName, this);
return true;
}

MipMap mipMap;
decompress(mipMap, *_mipMaps[0], _formatRaw);
Graphics::dumpTGA(fileName, mipMap.data, mipMap.width, mipMap.height, kPixelFormatRGBA);
decompress(mipMap, *_mipMaps[0], _format);
Graphics::dumpTGA(fileName, mipMap.data, mipMap.width, mipMap.height, kPixelFormatR8G8B8A8);

return true;
}

uint32 ImageDecoder::calculateSizeInBytes(int width, int height, PixelFormat format) {
switch (format) {
case kPixelFormatR8G8B8:
case kPixelFormatB8G8R8:
return width * height * 3;

case kPixelFormatR8G8B8A8:
case kPixelFormatB8G8R8A8:
return width * height * 4;

case kPixelFormatA1R5G5B5:
case kPixelFormatR5G6B5:
return width * height * 2;

case kPixelFormatDXT1:
return ((width + 3) / 4) * ((height + 3) / 4) * 8;

case kPixelFormatDXT3:
return ((width + 3) / 4) * ((height + 3) / 4) * 16;

case kPixelFormatDXT5:
return ((width + 3) / 4) * ((height + 3) / 4) * 16;

default:
throw Common::Exception("Can't calculate the size of an image with an invalid pixel format");
};

return 0;
}

bool ImageDecoder::isCompressed(PixelFormat format) {
return (format == kPixelFormatDXT1) ||
(format == kPixelFormatDXT3) ||
(format == kPixelFormatDXT5);
}

bool ImageDecoder::hasAlpha(PixelFormat format) {
return (kPixelFormatR8G8B8A8) ||
(kPixelFormatB8G8R8A8) ||
(kPixelFormatA1R5G5B5) ||
(kPixelFormatDXT3) ||
(kPixelFormatDXT5);
}

} // End of namespace Graphics
25 changes: 12 additions & 13 deletions src/graphics/images/decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,8 @@ class ImageDecoder {
/** Does the image data have alpha? .*/
bool hasAlpha() const;

/** Return the image data's general format. */
PixelFormat getFormat() const;
/** Return the image data's raw format. */
PixelFormatRaw getFormatRaw() const;
/** Return the image data pixel's type. */
PixelDataType getDataType() const;
/** Return the image data's format. */
PixelFormat getFormat() const;

/** Return the number of mip maps contained in the image. */
uint32 getMipMapCount() const;
Expand All @@ -90,17 +86,20 @@ class ImageDecoder {
/** Dump the image into a TGA. */
bool dumpTGA(const Common::UString &fileName) const;

protected:
bool _compressed;
bool _hasAlpha;

PixelFormat _format;
PixelFormatRaw _formatRaw;
PixelDataType _dataType;
/** Calculate the size in bytes of an image of the given size and pixel format. */
static uint32 calculateSizeInBytes(int width, int height, PixelFormat format);
/** Check whether a pixel format is compressed. */
static bool isCompressed(PixelFormat format);
/** Check whether a pixel format has an alpha channel. */
static bool hasAlpha(PixelFormat format);

protected:
PixelFormat _format;

std::vector<MipMap *> _mipMaps;

static void decompress(MipMap &out, const MipMap &in, PixelFormatRaw format);
static void decompress(MipMap &out, const MipMap &in, PixelFormat format);
};

} // End of namespace Graphics
Expand Down
8 changes: 4 additions & 4 deletions src/graphics/images/dumptga.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,25 @@
namespace Graphics {

static void writePixel(Common::DumpFile &file, const byte *&data, PixelFormat format) {
if (format == kPixelFormatRGB) {
if (format == kPixelFormatR8G8B8) {
file.writeByte(data[2]);
file.writeByte(data[1]);
file.writeByte(data[0]);
file.writeByte(0xFF);
data += 3;
} else if (format == kPixelFormatBGR) {
} else if (format == kPixelFormatB8G8R8) {
file.writeByte(data[0]);
file.writeByte(data[1]);
file.writeByte(data[2]);
file.writeByte(0xFF);
data += 3;
} else if (format == kPixelFormatRGBA) {
} else if (format == kPixelFormatR8G8B8A8) {
file.writeByte(data[2]);
file.writeByte(data[1]);
file.writeByte(data[0]);
file.writeByte(data[3]);
data += 4;
} else if (format == kPixelFormatBGRA) {
} else if (format == kPixelFormatB8G8R8A8) {
file.writeByte(data[0]);
file.writeByte(data[1]);
file.writeByte(data[2]);
Expand Down
6 changes: 1 addition & 5 deletions src/graphics/images/sbm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,7 @@
namespace Graphics {

SBM::SBM(Common::SeekableReadStream &sbm) {
_compressed = false;
_hasAlpha = true;
_format = kPixelFormatBGRA;
_formatRaw = kPixelFormatRGBA8;
_dataType = kPixelDataType8;
_format = kPixelFormatB8G8R8A8;

load(sbm);
}
Expand Down
6 changes: 1 addition & 5 deletions src/graphics/images/surface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,7 @@ namespace Graphics {
Surface::Surface(int width, int height) {
assert((width > 0) && (height > 0));

_compressed = false;
_hasAlpha = true;
_format = kPixelFormatBGRA;
_formatRaw = kPixelFormatRGBA8;
_dataType = kPixelDataType8;
_format = kPixelFormatB8G8R8A8;

_mipMaps.push_back(new MipMap);

Expand Down

0 comments on commit bc08795

Please sign in to comment.