GetCompressedSize() public static method

Calculates the compressed size of an image with given parameters.
public static GetCompressedSize ( int numMipmaps, ImageEngineFormat format, int width, int height ) : int
numMipmaps int Number of mipmaps in image. JPG etc only have 1.
format ImageEngineFormat Format of image.
width int Width of image (top mip if mip-able)
height int Height of image (top mip if mip-able)
return int
        byte[] AttemptSaveUsingOriginalData(ImageFormats.ImageEngineFormatDetails destFormatDetails, MipHandling GenerateMips, int desiredMaxDimension, int mipToSave, AlphaSettings alphaSetting)
        {
            int        start      = 0;
            int        destStart  = 0;
            int        length     = OriginalData.Length;
            int        newWidth   = Width;
            int        newHeight  = Height;
            DDS_Header tempHeader = null;

            byte[] data             = null;
            byte[] tempOriginalData = OriginalData;

            if (destFormatDetails.IsDDS)
            {
                destStart = destFormatDetails.HeaderSize;
                start     = destStart;

                int mipCount = 0;

                if (mipToSave != 0)
                {
                    mipCount  = 1;
                    newWidth  = MipMaps[mipToSave].Width;
                    newHeight = MipMaps[mipToSave].Height;

                    start  = ImageFormats.GetCompressedSize(mipToSave, destFormatDetails, Width, Height);
                    length = ImageFormats.GetCompressedSize(1, destFormatDetails, newWidth, newHeight);
                }
                else if (desiredMaxDimension != 0 && desiredMaxDimension < Width && desiredMaxDimension < Height)
                {
                    int index = MipMaps.FindIndex(t => t.Width < desiredMaxDimension && t.Height < desiredMaxDimension);

                    // If none found, do a proper save and see what happens.
                    if (index == -1)
                    {
                        return(ImageEngine.Save(MipMaps, destFormatDetails, GenerateMips, alphaSetting, desiredMaxDimension, mipToSave));
                    }

                    mipCount -= index;
                    newWidth  = MipMaps[index].Width;
                    newHeight = MipMaps[index].Height;

                    start  = ImageFormats.GetCompressedSize(index, destFormatDetails, Width, Height);
                    length = ImageFormats.GetCompressedSize(mipCount, destFormatDetails, newWidth, newHeight);
                }
                else
                {
                    if (alphaSetting == AlphaSettings.RemoveAlphaChannel)
                    {
                        // Can't edit alpha directly in premultiplied formats. Not easily anyway.
                        if (destFormatDetails.IsPremultipliedFormat)
                        {
                            return(ImageEngine.Save(MipMaps, destFormatDetails, GenerateMips, alphaSetting, desiredMaxDimension, mipToSave));
                        }


                        // DDS Formats only
                        switch (destFormatDetails.Format)
                        {
                        // Excluded cos they have no true alpha
                        case ImageEngineFormat.DDS_A8:
                        case ImageEngineFormat.DDS_A8L8:
                        case ImageEngineFormat.DDS_ATI1:
                        case ImageEngineFormat.DDS_ATI2_3Dc:
                        case ImageEngineFormat.DDS_V8U8:
                        case ImageEngineFormat.DDS_G16_R16:
                        case ImageEngineFormat.DDS_G8_L8:
                        case ImageEngineFormat.DDS_R5G6B5:
                        case ImageEngineFormat.DDS_RGB_8:
                        case ImageEngineFormat.DDS_DXT1:
                            break;

                        // Exluded cos they're alpha isn't easily edited
                        case ImageEngineFormat.DDS_DXT2:
                        case ImageEngineFormat.DDS_DXT4:
                            break;

                        // Excluded cos they're currently unsupported
                        case ImageEngineFormat.DDS_CUSTOM:
                        case ImageEngineFormat.DDS_DX10:
                        case ImageEngineFormat.DDS_ARGB_4:
                            break;

                        case ImageEngineFormat.DDS_ABGR_8:
                        case ImageEngineFormat.DDS_ARGB_32F:
                        case ImageEngineFormat.DDS_ARGB_8:
                        case ImageEngineFormat.DDS_DXT3:
                        case ImageEngineFormat.DDS_DXT5:
                            tempOriginalData = new byte[OriginalData.Length];
                            Array.Copy(OriginalData, tempOriginalData, OriginalData.Length);

                            // Edit alpha values
                            int    alphaStart = 128;
                            int    alphaJump  = 0;
                            byte[] alphaBlock = null;
                            if (destFormatDetails.IsBlockCompressed)
                            {
                                alphaJump  = 16;
                                alphaBlock = new byte[8];
                                for (int i = 0; i < 8; i++)
                                {
                                    alphaBlock[i] = 255;
                                }
                            }
                            else
                            {
                                alphaJump  = destFormatDetails.ComponentSize * 4;
                                alphaBlock = new byte[destFormatDetails.ComponentSize];

                                switch (destFormatDetails.ComponentSize)
                                {
                                case 1:
                                    alphaBlock[0] = 255;
                                    break;

                                case 2:
                                    alphaBlock = BitConverter.GetBytes(ushort.MaxValue);
                                    break;

                                case 4:
                                    alphaBlock = BitConverter.GetBytes(1f);
                                    break;
                                }
                            }

                            for (int i = alphaStart; i < OriginalData.Length; i += alphaJump)
                            {
                                Array.Copy(alphaBlock, 0, tempOriginalData, i, alphaBlock.Length);
                            }

                            break;
                        }
                    }


                    switch (GenerateMips)
                    {
                    case MipHandling.KeepExisting:
                        mipCount = NumMipMaps;
                        break;

                    case MipHandling.Default:
                        if (NumMipMaps > 1)
                        {
                            mipCount = NumMipMaps;
                        }
                        else
                        {
                            goto case MipHandling.GenerateNew;      // Eww goto...
                        }
                        break;

                    case MipHandling.GenerateNew:
                        ImageEngine.DestroyMipMaps(MipMaps);
                        ImageEngine.TestDDSMipSize(MipMaps, destFormatDetails, Width, Height, out double fixXScale, out double fixYScale, GenerateMips);

                        // Wrong sizing, so can't use original data anyway.
                        if (fixXScale != 0 || fixYScale != 0)
                        {
                            return(ImageEngine.Save(MipMaps, destFormatDetails, GenerateMips, alphaSetting, desiredMaxDimension, mipToSave));
                        }


                        mipCount = DDSGeneral.BuildMipMaps(MipMaps);

                        // Compress mipmaps excl top
                        byte[] formattedMips = DDSGeneral.Save(MipMaps.GetRange(1, MipMaps.Count - 1), destFormatDetails, alphaSetting);
                        if (formattedMips == null)
                        {
                            return(null);
                        }

                        // Get top mip size and create destination array
                        length = ImageFormats.GetCompressedSize(0, destFormatDetails, newWidth, newHeight);     // Should be the length of the top mipmap.
                        data   = new byte[formattedMips.Length + length];

                        // Copy smaller mips to destination
                        Array.Copy(formattedMips, destFormatDetails.HeaderSize, data, length, formattedMips.Length - destFormatDetails.HeaderSize);
                        break;

                    case MipHandling.KeepTopOnly:
                        mipCount = 1;
                        length   = ImageFormats.GetCompressedSize(1, destFormatDetails, newWidth, newHeight);
                        break;
                    }
                }

                // Header
                tempHeader = new DDS_Header(mipCount, newHeight, newWidth, destFormatDetails.Format, destFormatDetails.DX10Format);
            }

            // Use existing array, otherwise create one.
            data = data ?? new byte[length];
            Array.Copy(tempOriginalData, start, data, destStart, length - destStart);

            // Write header if existing (DDS Only)
            if (tempHeader != null)
            {
                tempHeader.WriteToArray(data, 0);
            }

            return(data);
        }