CSharpImageLibrary.DDS.DDSGeneral.GetCompressedSizeUpToIndex C# (CSharp) Method

GetCompressedSizeUpToIndex() static private method

static private GetCompressedSizeUpToIndex ( double mipIndex, ImageEngineFormat format, int baseWidth, int baseHeight ) : int
mipIndex double
format ImageEngineFormat
baseWidth int
baseHeight int
return int
        internal static int GetCompressedSizeUpToIndex(double mipIndex, ImageEngineFormat format, int baseWidth, int baseHeight)
        {
            /*
                Mipmapping halves both dimensions per mip down. Dimensions are then divided by 4 if block compressed as a texel is 4x4 pixels.
                e.g. 4096 x 4096 block compressed texture with 8 byte blocks e.g. DXT1
                Sizes of mipmaps:
                    4096 / 4 x 4096 / 4 x 8
                    (4096 / 4 / 2) x (4096 / 4 / 2) x 8
                    (4096 / 4 / 2 / 2) x (4096 / 4 / 2 / 2) x 8

                Pattern: Each dimension divided by 2 per mip size decreased.
                Thus, total is divided by 4.
                    Size of any mip = Sum(1/4^n) x divWidth x divHeight x blockSize,
                        where n is the desired mip (0 based),
                        divWidth and divHeight are the block compress adjusted dimensions (uncompressed textures lead to just original dimensions, block compressed are divided by 4)

                Turns out the partial sum of the infinite sum: Sum(1/4^n) = 1/3 x (4 - 4^-n). Who knew right?
            */

            // TODO: DDS going down past 4x4

            double divisor = 1;
            if (ImageFormats.IsBlockCompressed(format))
                divisor = 4;

            double shift = 1d / (4 << (int)(2 * (mipIndex - 1)));

            if (mipIndex == 0)
                shift = 1d;
            else if (mipIndex == -1)
                shift = 4d;

            double sumPart = mipIndex == -1 ? 0 :
                (1d / 3d) * (4d - shift);   // Shifting represents 4^-mipIndex. Math.Pow seems slow.

            double totalSize = 128 + (sumPart * ImageFormats.GetBlockSize(format) * (baseWidth / divisor) * (baseHeight / divisor));

            return (int)totalSize;
        }