/* SPDX-License-Identifier: GPL-2.0-or-later */ /** \file * \ingroup imbdds */ /* * This file is based on a similar file from the NVIDIA texture tools * (http://nvidia-texture-tools.googlecode.com/) * * Original license from NVIDIA follows. */ /* Copyright NVIDIA Corporation 2007 -- Ignacio Castano * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #pragma once #include #include #include #include /** DXT1 block. */ struct BlockDXT1 { Color16 col0; Color16 col1; union { uint8 row[4]; uint indices; }; bool isFourColorMode() const; uint evaluatePalette(Color32 color_array[4]) const; uint evaluatePaletteNV5x(Color32 color_array[4]) const; /** Evaluate palette assuming 3 color block. */ void evaluatePalette3(Color32 color_array[4]) const; /** Evaluate palette assuming 4 color block. */ void evaluatePalette4(Color32 color_array[4]) const; void decodeBlock(ColorBlock *block) const; void decodeBlockNV5x(ColorBlock *block) const; void setIndices(const int *idx); /** Flip DXT1 block vertically. */ void flip4(); /** Flip half DXT1 block vertically. */ void flip2(); }; /** Return true if the block uses four color mode, false otherwise. */ inline bool BlockDXT1::isFourColorMode() const { return col0.u > col1.u; } /** DXT3 alpha block with explicit alpha. */ struct AlphaBlockDXT3 { union { struct { uint alpha0 : 4; uint alpha1 : 4; uint alpha2 : 4; uint alpha3 : 4; uint alpha4 : 4; uint alpha5 : 4; uint alpha6 : 4; uint alpha7 : 4; uint alpha8 : 4; uint alpha9 : 4; uint alphaA : 4; uint alphaB : 4; uint alphaC : 4; uint alphaD : 4; uint alphaE : 4; uint alphaF : 4; }; uint16 row[4]; }; void decodeBlock(ColorBlock *block) const; /** Flip DXT3 alpha block vertically. */ void flip4(); /** Flip half DXT3 alpha block vertically. */ void flip2(); }; /** DXT3 block. */ struct BlockDXT3 { AlphaBlockDXT3 alpha; BlockDXT1 color; void decodeBlock(ColorBlock *block) const; void decodeBlockNV5x(ColorBlock *block) const; /** Flip DXT3 block vertically. */ void flip4(); /** Flip half DXT3 block vertically. */ void flip2(); }; /** DXT5 alpha block. */ struct AlphaBlockDXT5 { /* uint64 unions do not compile on all platforms */ #if 0 union { struct { uint64 alpha0 : 8; /* 8 */ uint64 alpha1 : 8; /* 16 */ uint64 bits0 : 3; /* 3 - 19 */ uint64 bits1 : 3; /* 6 - 22 */ uint64 bits2 : 3; /* 9 - 25 */ uint64 bits3 : 3; /* 12 - 28 */ uint64 bits4 : 3; /* 15 - 31 */ uint64 bits5 : 3; /* 18 - 34 */ uint64 bits6 : 3; /* 21 - 37 */ uint64 bits7 : 3; /* 24 - 40 */ uint64 bits8 : 3; /* 27 - 43 */ uint64 bits9 : 3; /* 30 - 46 */ uint64 bitsA : 3; /* 33 - 49 */ uint64 bitsB : 3; /* 36 - 52 */ uint64 bitsC : 3; /* 39 - 55 */ uint64 bitsD : 3; /* 42 - 58 */ uint64 bitsE : 3; /* 45 - 61 */ uint64 bitsF : 3; /* 48 - 64 */ }; uint64 u; }; #endif uint64 u; uint8 alpha0() const { return u & 0xffLL; } uint8 alpha1() const { return (u >> 8) & 0xffLL; } uint8 bits0() const { return (u >> 16) & 0x7LL; } uint8 bits1() const { return (u >> 19) & 0x7LL; } uint8 bits2() const { return (u >> 22) & 0x7LL; } uint8 bits3() const { return (u >> 25) & 0x7LL; } uint8 bits4() const { return (u >> 28) & 0x7LL; } uint8 bits5() const { return (u >> 31) & 0x7LL; } uint8 bits6() const { return (u >> 34) & 0x7LL; } uint8 bits7() const { return (u >> 37) & 0x7LL; } uint8 bits8() const { return (u >> 40) & 0x7LL; } uint8 bits9() const { return (u >> 43) & 0x7LL; } uint8 bitsA() const { return (u >> 46) & 0x7LL; } uint8 bitsB() const { return (u >> 49) & 0x7LL; } uint8 bitsC() const { return (u >> 52) & 0x7LL; } uint8 bitsD() const { return (u >> 55) & 0x7LL; } uint8 bitsE() const { return (u >> 58) & 0x7LL; } uint8 bitsF() const { return (u >> 61) & 0x7LL; } void evaluatePalette(uint8 alpha[8]) const; void evaluatePalette8(uint8 alpha[8]) const; void evaluatePalette6(uint8 alpha[8]) const; void indices(uint8 index_array[16]) const; uint index(uint index) const; void setIndex(uint index, uint value); void decodeBlock(ColorBlock *block) const; void flip4(); void flip2(); }; /** DXT5 block. */ struct BlockDXT5 { AlphaBlockDXT5 alpha; BlockDXT1 color; void decodeBlock(ColorBlock *block) const; void decodeBlockNV5x(ColorBlock *block) const; /** Flip DXT5 block vertically. */ void flip4(); /** Flip half DXT5 block vertically. */ void flip2(); }; /** ATI1 block. */ struct BlockATI1 { AlphaBlockDXT5 alpha; /** Decode ATI1 block. */ void decodeBlock(ColorBlock *block) const; /** Flip ATI1 block vertically. */ void flip4(); /** Flip half ATI1 block vertically. */ void flip2(); }; /** ATI2 block. */ struct BlockATI2 { AlphaBlockDXT5 x; AlphaBlockDXT5 y; /** Decode ATI2 block. */ void decodeBlock(ColorBlock *block) const; /** Flip ATI2 block vertically. */ void flip4(); /** Flip half ATI2 block vertically. */ void flip2(); }; /** CTX1 block. */ struct BlockCTX1 { uint8 col0[2]; uint8 col1[2]; union { uint8 row[4]; uint indices; }; void evaluatePalette(Color32 color_array[4]) const; void setIndices(const int *idx); void decodeBlock(ColorBlock *block) const; /** Flip CTX1 block vertically. */ void flip4(); /** Flip half CTX1 block vertically. */ void flip2(); }; void mem_read(Stream &mem, BlockDXT1 &block); void mem_read(Stream &mem, AlphaBlockDXT3 &block); void mem_read(Stream &mem, BlockDXT3 &block); void mem_read(Stream &mem, AlphaBlockDXT5 &block); void mem_read(Stream &mem, BlockDXT5 &block); void mem_read(Stream &mem, BlockATI1 &block); void mem_read(Stream &mem, BlockATI2 &block); void mem_read(Stream &mem, BlockCTX1 &block);