Mercurial > love-experiments
diff src/libraries/ddsparse/ddsparse.cpp @ 1422:377f9dad7a2d image-CompressedData
Replaced the devil love.image module with love.image.magpie, which can decide which image library to use in a similar manner to love.sound.lullaby. Some rough edges still exist.
love.filesystem.newFileData now accepts filepaths and File objects.
| author | Alex Szpakowski <slime73@gmail.com> |
|---|---|
| date | Sun, 07 Apr 2013 17:18:34 -0300 |
| parents | aa603d1b03bc |
| children |
line wrap: on
line diff
--- a/src/libraries/ddsparse/ddsparse.cpp Fri Apr 05 18:55:44 2013 -0300 +++ b/src/libraries/ddsparse/ddsparse.cpp Sun Apr 07 17:18:34 2013 -0300 @@ -36,9 +36,9 @@ static inline uint32_t FourCC(char a, char b, char c, char d) { uint32_t fcc = ((uint32_t) a) - | (((uint32_t) b) << 8) - | (((uint32_t) c) << 16) - | (((uint32_t) d) << 24); + | (((uint32_t) b) << 8) + | (((uint32_t) c) << 16) + | (((uint32_t) d) << 24); return fcc; } @@ -86,46 +86,54 @@ return true; } -Parser::Parser(const void *data, size_t dataSize, Options opts) +bool Parser::isCompressedDDS(const void *data, size_t dataSize) +{ + if (!isDDS(data, dataSize)) + return false; + + const uint8_t *readData = (const uint8_t *) data; + ptrdiff_t offset = sizeof(uint32_t); + + DDSHeader *header = (DDSHeader *) &readData[offset]; + offset += sizeof(DDSHeader); + + // Check for DX10 extension. + if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == FourCC('D','X','1','0'))) + { + DDSHeader10 *header10 = (DDSHeader10 *) &readData[offset]; + return parseDX10Format(header10->dxgiFormat) != FORMAT_UNKNOWN; + } + + return parseDDSFormat(header->format) != FORMAT_UNKNOWN; +} + +Parser::Parser(const void *data, size_t dataSize) : format(FORMAT_UNKNOWN) - , options(opts) { parseData(data, dataSize); } Parser::Parser(const Parser &other) - : format(other.format) - , options(other.options) + : texData(other.texData) + , format(other.format) { - std::vector<Image>::const_iterator it; - for (it = other.texData.begin(); it != other.texData.end(); ++it) - { - Image img = *it; +} - if ((options & OPTIONS_COPY_DATA) && img.dataSize > 0) - { - uint8_t *data = 0; - try - { - data = new uint8_t[img.dataSize]; - } - catch (std::exception &) - { - clearData(); - throw; - } - memcpy(data, it->data, img.dataSize); - img.data = data; - } +Parser::Parser() + : format(FORMAT_UNKNOWN) +{ +} - texData.push_back(img); - } +Parser &Parser::operator = (const Parser &other) +{ + texData = other.texData; + format = other.format; + + return *this; } Parser::~Parser() { - // Delete any data we created. - clearData(); } Format Parser::getFormat() const @@ -146,12 +154,7 @@ return texData.size(); } -bool Parser::ownsData() const -{ - return (options & OPTIONS_COPY_DATA) != 0; -} - -Format Parser::parseDDSFormat(const DDSPixelFormat &fmt) const +Format Parser::parseDDSFormat(const DDSPixelFormat &fmt) { if (fmt.flags & DDPF_FOURCC) { @@ -161,8 +164,16 @@ return FORMAT_DXT3; else if (fmt.fourCC == FourCC('D','X','T','5')) return FORMAT_DXT5; + else if (fmt.fourCC == FourCC('A','T','I','1')) + return FORMAT_BC4; else if (fmt.fourCC == FourCC('A','T','I','2')) return FORMAT_BC5; + else if (fmt.fourCC == FourCC('B','C','4','U')) + return FORMAT_BC4; + else if (fmt.fourCC == FourCC('B','C','4','S')) + return FORMAT_BC4s; + else if (fmt.fourCC == FourCC('B','C','5','U')) + return FORMAT_BC5; else if (fmt.fourCC == FourCC('B','C','5','S')) return FORMAT_BC5s; } @@ -170,7 +181,7 @@ return FORMAT_UNKNOWN; } -Format Parser::parseDX10Format(DXGIFormat fmt) const +Format Parser::parseDX10Format(DXGIFormat fmt) { Format f = FORMAT_UNKNOWN; @@ -191,19 +202,34 @@ case DXGI_FORMAT_BC3_UNORM_SRGB: f = FORMAT_DXT5; break; - case DXGI_FORMAT_BC5_SNORM: - f = FORMAT_BC5s; + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + f = FORMAT_BC4; + break; + case DXGI_FORMAT_BC4_SNORM: + f = FORMAT_BC4s; break; case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_BC5_UNORM: f = FORMAT_BC5; break; + case DXGI_FORMAT_BC5_SNORM: + f = FORMAT_BC5s; + break; + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + f = FORMAT_BC6H; + break; + case DXGI_FORMAT_BC6H_SF16: + f = FORAMT_BC6Hs; + break; case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: f = FORMAT_BC7; break; case DXGI_FORMAT_BC7_UNORM_SRGB: f = FORMAT_BC7srgb; + break; default: break; } @@ -248,6 +274,7 @@ bool Parser::parseTexData(const uint8_t *data, size_t dataSize, Format fmt, int w, int h, int mips) { size_t offset = 0; + std::vector<Image> newTexData; for (int i = 0; i < mips; i++) { @@ -259,33 +286,12 @@ // Make sure the data size is valid. if (img.dataSize == 0 || (offset + img.dataSize) > dataSize) - { - // Clean up any data we allocated previously. - clearData(); return false; - } - // Create our own copy of the data, if requested. - if (options & OPTIONS_COPY_DATA) - { - uint8_t *newData = 0; - try - { - newData = new uint8_t[img.dataSize]; - } - catch (std::exception &) - { - // Clean up before throwing. - clearData(); - throw; - } - memcpy(newData, &data[offset], img.dataSize); - img.data = newData; - } - else - img.data = &data[offset]; + // Store the memory address of the data representing this mip level. + img.data = &data[offset]; - texData.push_back(img); + newTexData.push_back(img); // Move to the next mip level. offset += img.dataSize; @@ -294,6 +300,8 @@ h = std::max(h / 2, 1); } + texData = newTexData; + return true; } @@ -347,20 +355,4 @@ return parseTexData(&readData[offset], dataSize - offset, format, w, h, mips); } -void Parser::clearData() -{ - if (options & OPTIONS_COPY_DATA) - { - // Delete any data we created. - std::vector<Image>::iterator it; - for (it = texData.begin(); it != texData.end(); ++it) - { - delete[] it->data; - it->data = 0; - } - } - - texData.clear(); -} - } // dds
