示例#1
0
        internal static unsafe byte[] Compress(byte[] data, ref TextureFormat format, Vector2I dimensions, bool HasAlpha, bool IsPunchThroughAlpha, bool IsMasky, bool HasR, bool HasG, bool HasB)
        {
            if (!BlockCompressionFunctional)
            {
                return(null);
            }

            var oldSpriteFormat = format;

            FlipColorBytes(data);

            try {
                var bitmapData = data;

                using var compressor             = new Compressor();
                compressor.Input.AlphaMode       = (HasAlpha) ? AlphaMode.Premultiplied : AlphaMode.None;
                compressor.Input.GenerateMipmaps = false;
                var textureFormat =
                    (!HasAlpha) ?
                    TextureFormat.NoAlpha :
                    ((false && IsPunchThroughAlpha && Config.Resample.BlockCompression.Quality != CompressionQuality.Fastest) ?
                     TextureFormat.WithPunchthroughAlpha :
                     (IsMasky ?
                      TextureFormat.WithHardAlpha :
                      TextureFormat.WithAlpha));
                compressor.Compression.Format  = textureFormat;
                compressor.Compression.Quality = Config.Resample.BlockCompression.Quality;
                compressor.Compression.SetQuantization(true, true, IsPunchThroughAlpha);

                {
                    compressor.Compression.GetColorWeights(out var r, out var g, out var b, out var a);
                    a = HasAlpha ? (a * 20.0f) : 0.0f;
                    // Relative luminance of the various channels.
                    r = HasR ? (r * 0.2126f) : 0.0f;
                    g = HasG ? (g * 0.7152f) : 0.0f;
                    b = HasB ? (b * 0.0722f) : 0.0f;

                    compressor.Compression.SetColorWeights(r, g, b, a);
                }

                compressor.Output.IsSRGBColorSpace = true;
                compressor.Output.OutputHeader     = false;

                //public MipData (int width, int height, int rowPitch, IntPtr data, bool ownData = true)

                fixed(byte *p = bitmapData)
                {
                    using var mipData = new MipData(dimensions.Width, dimensions.Height, dimensions.Width * sizeof(int), (IntPtr)p, false);
                    compressor.Input.SetData(mipData, true);
                    var memoryBuffer = new byte[((SurfaceFormat)textureFormat).SizeBytes(dimensions.Area)];

                    using var stream = memoryBuffer.Stream();
                    if (compressor.Process(stream))
                    {
                        format = textureFormat;
                        return(memoryBuffer);
                    }
                    else
                    {
                        Debug.WarningLn($"Failed to use {(CompressionFormat)textureFormat} compression: " + compressor.LastErrorString);
                    }
                }
            }
            catch (Exception ex) {
                ex.PrintWarning();
                BlockCompressionFunctional = false;
            }
            format = oldSpriteFormat;
            FlipColorBytes(data);
            return(null);
        }
示例#2
0
    internal static unsafe bool Encode(
        ReadOnlySpan <Color8> data,
        ref TextureFormat format,
        Vector2I dimensions,
        bool hasAlpha,
        bool isPunchthroughAlpha,
        bool isMasky,
        bool hasR,
        bool hasG,
        bool hasB,
        out PinnedSpan <byte> result
        )
    {
        if (!BlockCompressionFunctional)
        {
            result = default;
            return(false);
        }

        var oldSpriteFormat = format;

        try {
            using var compressor             = new Compressor();
            compressor.Input.AlphaMode       = (hasAlpha) ? AlphaMode.Premultiplied : AlphaMode.None;
            compressor.Input.GenerateMipmaps = false;
            var textureFormat = BlockEncoderCommon.GetBestTextureFormat(hasAlpha, isPunchthroughAlpha, isMasky);
            compressor.Compression.Format  = textureFormat;
            compressor.Compression.Quality = Config.Resample.BlockCompression.Quality;
            compressor.Compression.SetQuantization(true, true, isPunchthroughAlpha);

            {
                compressor.Compression.GetColorWeights(out var r, out var g, out var b, out var a);
                a = hasAlpha ? (a * 20.0f) : 0.0f;
                // Relative luminance of the various channels.
                r = hasR ? (r * 0.2126f) : 0.0f;
                g = hasG ? (g * 0.7152f) : 0.0f;
                b = hasB ? (b * 0.0722f) : 0.0f;

                compressor.Compression.SetColorWeights(r, g, b, a);
            }

            compressor.Output.IsSRGBColorSpace = true;
            compressor.Output.OutputHeader     = false;

            //public MipData (int width, int height, int rowPitch, IntPtr data, bool ownData = true)
            fixed(byte *p = data.Cast <byte>())
            {
                using var mipData = new MipData(dimensions.Width, dimensions.Height, dimensions.Width * sizeof(int), (IntPtr)p, false);
                compressor.Input.SetData(mipData, false);
                var memoryBuffer = GC.AllocateUninitializedArray <byte>(((SurfaceFormat)textureFormat).SizeBytes(dimensions.Area), pinned: true);

                using var stream = memoryBuffer.Stream();
                if (compressor.Process(stream))
                {
                    format = textureFormat;
                    result = memoryBuffer;
                    return(true);
                }
                else
                {
                    Debug.Warning($"Failed to use {(CompressionFormat)textureFormat} compression: " + compressor.LastErrorString);
                    Debug.Warning($"Dimensions: [{dimensions.Width}, {dimensions.Height}]");
                }
            }
        }
        catch (Exception ex) {
            ex.PrintWarning();
            BlockCompressionFunctional = false;
        }
        format = oldSpriteFormat;

        result = default;
        return(false);
    }