예제 #1
0
    internal static 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
        )
    {
        TextureFormat resultFormat = hasAlpha ? TextureFormat.BC3 : TextureFormat.BC1;
        var           resultBytes  = SpanExt.MakePinned <byte>(RequiredSize(dimensions, hasAlpha));

        var compressionMode = Configuration.Config.Resample.BlockCompression.Quality switch {
            CompressionQuality.Low => CompressionMode.Normal,
            CompressionQuality.Medium => CompressionMode.Dither,
            CompressionQuality.High => CompressionMode.HighQuality,
            _ => ThrowHelper.ThrowInvalidOperationException <CompressionMode>($"Unknown Quality: '{Configuration.Config.Resample.BlockCompression.Quality}'")
        };

        CompressDxt(resultBytes, data.AsBytes(), dimensions, hasAlpha, compressionMode);

        result = resultBytes;
        format = resultFormat;
        return(true);
    }
예제 #2
0
    private static Span <Color16> Apply(
        Config?config,
        uint scaleMultiplier,
        ReadOnlySpan <Color16> sourceData,
        Vector2I sourceSize,
        Span <Color16> targetData,
        Vector2I targetSize
        )
    {
        if (config is null)
        {
            throw new ArgumentNullException(nameof(config));
        }

        if (scaleMultiplier < MinScale || scaleMultiplier > MaxScale || !NumericsExt.IsPow2(scaleMultiplier))
        {
            throw new ArgumentOutOfRangeException(nameof(scaleMultiplier));
        }

        if (sourceSize.X * sourceSize.Y > sourceData.Length)
        {
            throw new ArgumentOutOfRangeException(nameof(sourceData));
        }

        var targetSizeCalculated = sourceSize * scaleMultiplier;

        if (targetSize != targetSizeCalculated)
        {
            throw new ArgumentOutOfRangeException(nameof(targetSize));
        }

        if (targetData.IsEmpty)
        {
            targetData = SpanExt.MakePinned <Color16>(targetSize.Area);
        }
        else
        {
            if (targetSize.Area > targetData.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(targetData));
            }
        }

        var scalerInstance = new Scaler(
            configuration: in config,
            scaleMultiplier: scaleMultiplier,
            sourceSize: sourceSize,
            targetSize: targetSize
            );

        scalerInstance.Scale(sourceData, targetData);
        return(targetData);
    }