Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small changes to the main entry classes #14

Merged
merged 9 commits into from
Jan 12, 2021
32 changes: 0 additions & 32 deletions BCnEnc.Net/Decoder/Bc7Decoder.cs

This file was deleted.

247 changes: 99 additions & 148 deletions BCnEnc.Net/Decoder/BcBlockDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,152 +5,103 @@

namespace BCnEncoder.Decoder
{
internal interface IBcBlockDecoder {
RawBlock4X4Rgba32[,] Decode(ReadOnlySpan<byte> data, int pixelWidth, int pixelHeight, out int blockWidth,
out int blockHeight);
}

internal class Bc1NoAlphaDecoder : IBcBlockDecoder {
public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan<byte> data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) {
blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f);
blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f);

if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf<Bc1Block>())) {
throw new InvalidDataException();
}

var encodedBlocks = MemoryMarshal.Cast<byte, Bc1Block>(data);

RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight];

for (int x = 0; x < blockWidth; x++) {
for (int y = 0; y < blockHeight; y++) {
output[x, y] = encodedBlocks[x + y * blockWidth].Decode(false);
}
}

return output;
}
}

internal class Bc1ADecoder : IBcBlockDecoder {
public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan<byte> data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) {
blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f);
blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f);

if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf<Bc1Block>())) {
throw new InvalidDataException();
}

var encodedBlocks = MemoryMarshal.Cast<byte, Bc1Block>(data);

RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight];

for (int x = 0; x < blockWidth; x++) {
for (int y = 0; y < blockHeight; y++) {
output[x, y] = encodedBlocks[x + y * blockWidth].Decode(true);
}
}

return output;
}
}

internal class Bc2Decoder : IBcBlockDecoder {
public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan<byte> data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) {
blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f);
blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f);

if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf<Bc2Block>())) {
throw new InvalidDataException();
}

var encodedBlocks = MemoryMarshal.Cast<byte, Bc2Block>(data);

RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight];

for (int x = 0; x < blockWidth; x++) {
for (int y = 0; y < blockHeight; y++) {
output[x, y] = encodedBlocks[x + y * blockWidth].Decode();
}
}

return output;
}
}

internal class Bc3Decoder : IBcBlockDecoder {
public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan<byte> data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) {
blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f);
blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f);

if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf<Bc3Block>())) {
throw new InvalidDataException();
}

var encodedBlocks = MemoryMarshal.Cast<byte, Bc3Block>(data);

RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight];

for (int x = 0; x < blockWidth; x++) {
for (int y = 0; y < blockHeight; y++) {
output[x, y] = encodedBlocks[x + y * blockWidth].Decode();
}
}

return output;
}
}

internal class Bc4Decoder : IBcBlockDecoder {
private readonly bool redAsLuminance;
public Bc4Decoder(bool redAsLuminance) {
this.redAsLuminance = redAsLuminance;
}

public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan<byte> data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) {
blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f);
blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f);

if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf<Bc4Block>())) {
throw new InvalidDataException();
}

var encodedBlocks = MemoryMarshal.Cast<byte, Bc4Block>(data);

RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight];

for (int x = 0; x < blockWidth; x++) {
for (int y = 0; y < blockHeight; y++) {
output[x, y] = encodedBlocks[x + y * blockWidth].Decode(redAsLuminance);
}
}

return output;
}
}

internal class Bc5Decoder : IBcBlockDecoder {

public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan<byte> data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) {
blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f);
blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f);

if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf<Bc5Block>())) {
throw new InvalidDataException();
}

var encodedBlocks = MemoryMarshal.Cast<byte, Bc5Block>(data);

RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight];

for (int x = 0; x < blockWidth; x++) {
for (int y = 0; y < blockHeight; y++) {
output[x, y] = encodedBlocks[x + y * blockWidth].Decode();
}
}

return output;
}
}
internal interface IBcBlockDecoder
{
RawBlock4X4Rgba32[,] Decode(ReadOnlySpan<byte> data, int pixelWidth, int pixelHeight, out int blockWidth,
out int blockHeight);
}

internal abstract class BaseBcBlockDecoder<T> : IBcBlockDecoder
where T : struct
{
public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan<byte> data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight)
{
blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f);
blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f);

if (data.Length != blockWidth * blockHeight * Marshal.SizeOf<T>())
{
throw new InvalidDataException("Given data does not match expected length.");
}

var encodedBlocks = MemoryMarshal.Cast<byte, T>(data);

var output = new RawBlock4X4Rgba32[blockWidth, blockHeight];

for (var x = 0; x < blockWidth; x++)
{
for (var y = 0; y < blockHeight; y++)
{
output[x, y] = DecodeBlock(encodedBlocks[x + y * blockWidth]);
}
}

return output;
}

protected abstract RawBlock4X4Rgba32 DecodeBlock(T block);
}

internal class Bc1NoAlphaDecoder : BaseBcBlockDecoder<Bc1Block>
{
protected override RawBlock4X4Rgba32 DecodeBlock(Bc1Block block)
{
return block.Decode(false);
}
}

internal class Bc1ADecoder : BaseBcBlockDecoder<Bc1Block>
{
protected override RawBlock4X4Rgba32 DecodeBlock(Bc1Block block)
{
return block.Decode(true);
}
}

internal class Bc2Decoder : BaseBcBlockDecoder<Bc2Block>
{
protected override RawBlock4X4Rgba32 DecodeBlock(Bc2Block block)
{
return block.Decode();
}
}

internal class Bc3Decoder : BaseBcBlockDecoder<Bc3Block>
{
protected override RawBlock4X4Rgba32 DecodeBlock(Bc3Block block)
{
return block.Decode();
}
}

internal class Bc4Decoder : BaseBcBlockDecoder<Bc4Block>
{
private readonly bool redAsLuminance;

public Bc4Decoder(bool redAsLuminance)
{
this.redAsLuminance = redAsLuminance;
}

protected override RawBlock4X4Rgba32 DecodeBlock(Bc4Block block)
{
return block.Decode(redAsLuminance);
}
}

internal class Bc5Decoder : BaseBcBlockDecoder<Bc5Block>
{
protected override RawBlock4X4Rgba32 DecodeBlock(Bc5Block block)
{
return block.Decode();
}
}

internal class Bc7Decoder : BaseBcBlockDecoder<Bc7Block>
{
protected override RawBlock4X4Rgba32 DecodeBlock(Bc7Block block)
{
return block.Decode();
}
}
}
Loading