protected override void ReadBlock(SimpleBinaryStream stream, ref PixelColor[,] cache, int blockX) { blockX *= 4; PixelColor[] baseColor = new PixelColor[4]; ushort color0, color1; baseColor[0] = GetColorFromRGB565(color0 = stream.ReadUInt16()); baseColor[1] = GetColorFromRGB565(color1 = stream.ReadUInt16()); if (color0 > color1) { // baseColor[2] = (baseColor[0] * 2 + baseColor[1]) / 3; baseColor[2] = PixelColor.MAD(baseColor[0], 2, baseColor[1], 3); baseColor[3] = PixelColor.MAD(baseColor[1], 2, baseColor[0], 3); } else { baseColor[2] = PixelColor.AVG(baseColor[0], baseColor[1]); baseColor[3] = new PixelColor(0, 0, 0, 1f); } for (int y = 0; y < 4; y++) { byte index = stream.ReadByte(); cache[y, blockX + 0] = baseColor[(index >> 0) & 0x3]; cache[y, blockX + 1] = baseColor[(index >> 2) & 0x3]; cache[y, blockX + 2] = baseColor[(index >> 4) & 0x3]; cache[y, blockX + 3] = baseColor[(index >> 6) & 0x3]; } }
protected override void ReadBlock(SimpleBinaryStream stream, ref PixelColor[,] cache, int blockX) { base.ReadBlock(stream, ref cache, blockX); DXT5Reader.ReadBC3AlphaBlock(stream.ReadInt64(), ref cache, blockX * 4, (ref PixelColor pixel, float value) => { pixel.G = value; }); }
protected override void ReadBlock(SimpleBinaryStream stream, ref PixelColor[,] cache, int blockX) { long alphaData = stream.ReadInt64(); base.ReadBlock(stream, ref cache, blockX); ReadBC3AlphaBlock(alphaData, ref cache, blockX * 4, (ref PixelColor pixel, float value) => { pixel.A = value; }); }
public override void Read(PipelineWriter output) { using (SimpleBinaryStream stream = new SimpleBinaryStream(dataSource)) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { output.Write(ReadPixel(stream)); } } } }
protected override void ReadBlock(SimpleBinaryStream stream, ref PixelColor[,] cache, int blockX) { ulong alphaData = stream.ReadUInt64(); base.ReadBlock(stream, ref cache, blockX); blockX *= 4; int i = 0; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { int alpha = (int)((alphaData >> (i * 4)) & 0xF); i++; alpha = alpha << 4 | alpha; cache[y, blockX + x].A = alpha / 255f; } } }
protected abstract void ReadBlock(SimpleBinaryStream stream, ref PixelColor[,] cache, int blockX);
public override void Read(PipelineWriter output) { int blockWidth = Math.Max((width + 3) / 4, 1); int blockHeight = Math.Max((height + 3) / 4, 1); PixelColor[,] cache0 = new PixelColor[4, blockWidth * 4]; PixelColor[,] cache1 = new PixelColor[4, blockWidth * 4]; bool isPingPong = false; #if !NET40 System.Threading.Tasks.Task task = null; #endif using (SimpleBinaryStream stream = new SimpleBinaryStream(dataSource)) { for (int y = 0; y < blockHeight; y++) { if (isPingPong) { for (int x = 0; x < blockWidth; x++) ReadBlock(stream, ref cache1, x); } else { for (int x = 0; x < blockWidth; x++) ReadBlock(stream, ref cache0, x); } #if !NET40 if (task != null) task.Wait(); #endif bool pingPoing = isPingPong; int baseY = y; #if !NET40 task = System.Threading.Tasks.Task.Run((() => { #endif for (int y2 = 0; y2 < 4; y2++) { int currentY = baseY * 4 + y2; if (currentY < height) { if (pingPoing) { for (int x = 0; x < width; x++) output.Write(cache1[y2, x]); } else { for (int x = 0; x < width; x++) output.Write(cache0[y2, x]); } } } #if !NET40 })); #endif isPingPong = !isPingPong; } #if !NET40 task.Wait(); #endif } }
private PixelColor ReadPixel(SimpleBinaryStream stream) { float r = 0, g = 0, b = 0, a = 1.0f; switch (format) { case TextureFormat.B8G8R8A8_UNORM: b = UnormByteToSingle(stream.ReadByte()); g = UnormByteToSingle(stream.ReadByte()); r = UnormByteToSingle(stream.ReadByte()); a = UnormByteToSingle(stream.ReadByte()); break; case TextureFormat.B8G8R8X8_UNORM: b = UnormByteToSingle(stream.ReadByte()); g = UnormByteToSingle(stream.ReadByte()); r = UnormByteToSingle(stream.ReadByte()); stream.ReadByte(); break; case TextureFormat.R16G16_UNORM: r = UnormUShortToSingle(stream.ReadUInt16()); g = UnormUShortToSingle(stream.ReadUInt16()); break; case TextureFormat.R16G16F: r = HalfToSingle(stream.ReadUInt16()); g = HalfToSingle(stream.ReadUInt16()); break; case TextureFormat.R32_UINT: // not good for visual r = IntToSingle(stream.ReadUInt32()); break; case TextureFormat.A8_UNORM: r = UnormByteToSingle(stream.ReadByte()); break; case TextureFormat.R8G8B8A8_UNORM: r = UnormByteToSingle(stream.ReadByte()); g = UnormByteToSingle(stream.ReadByte()); b = UnormByteToSingle(stream.ReadByte()); a = UnormByteToSingle(stream.ReadByte()); break; case TextureFormat.R8G8B8A8_UINT: r = UnormByteToSingle(stream.ReadByte()); g = UnormByteToSingle(stream.ReadByte()); b = UnormByteToSingle(stream.ReadByte()); a = UnormByteToSingle(stream.ReadByte()); break; case TextureFormat.R16G16B16A16_UNORM: r = UnormUShortToSingle(stream.ReadUInt16()); g = UnormUShortToSingle(stream.ReadUInt16()); b = UnormUShortToSingle(stream.ReadUInt16()); a = UnormUShortToSingle(stream.ReadUInt16()); break; case TextureFormat.L8_UNORM: r = UnormByteToSingle(stream.ReadByte()); break; case TextureFormat.R8_UNORM: r = UnormByteToSingle(stream.ReadByte()); break; case TextureFormat.R16_UNORM: r = UnormUShortToSingle(stream.ReadUInt16()); break; case TextureFormat.R16F: r = HalfToSingle(stream.ReadUInt16()); break; case TextureFormat.D24_UNORM_S8_UINT: r = UnormInt24ToSingle(stream.ReadUInt24()); g = UnormByteToSingle(stream.ReadByte()); break; case TextureFormat.D24_UNORM_X8_UINT: r = UnormInt24ToSingle(stream.ReadUInt24()); stream.ReadByte(); break; case TextureFormat.D16_UNORM: r = UnormUShortToSingle(stream.ReadUInt16()); break; case TextureFormat.D32F: r = SingleToSingle(stream.ReadSingle()); break; case TextureFormat.L16_UNORM: r = UnormUShortToSingle(stream.ReadUInt16()); break; case TextureFormat.R16G16B16A16F: r = HalfToSingle(stream.ReadUInt16()); g = HalfToSingle(stream.ReadUInt16()); b = HalfToSingle(stream.ReadUInt16()); a = HalfToSingle(stream.ReadUInt16()); break; case TextureFormat.R32F: r = SingleToSingle(stream.ReadSingle()); break; case TextureFormat.R32G32B32F: r = SingleToSingle(stream.ReadSingle()); g = SingleToSingle(stream.ReadSingle()); b = SingleToSingle(stream.ReadSingle()); break; case TextureFormat.R32G32B32A32F: r = SingleToSingle(stream.ReadSingle()); g = SingleToSingle(stream.ReadSingle()); b = SingleToSingle(stream.ReadSingle()); a = SingleToSingle(stream.ReadSingle()); break; case TextureFormat.R11G11B10F: // unsupported! daze! stream.ReadUInt32(); break; case TextureFormat.R16G16B16: r = UShortToSingle(stream.ReadUInt16()); g = UShortToSingle(stream.ReadUInt16()); b = UShortToSingle(stream.ReadUInt16()); break; case TextureFormat.R8G8B8: r = UnormByteToSingle(stream.ReadByte()); g = UnormByteToSingle(stream.ReadByte()); b = UnormByteToSingle(stream.ReadByte()); break; case TextureFormat.B8G8R8: b = UnormByteToSingle(stream.ReadByte()); g = UnormByteToSingle(stream.ReadByte()); r = UnormByteToSingle(stream.ReadByte()); break; case TextureFormat.R32G32B32A32_UINT: // not good for visual r = IntToSingle(stream.ReadUInt32()); g = IntToSingle(stream.ReadUInt32()); b = IntToSingle(stream.ReadUInt32()); a = IntToSingle(stream.ReadUInt32()); break; case TextureFormat.R8_UINT: r = UnormByteToSingle(stream.ReadByte()); break; case TextureFormat.R16_UINT: r = UShortToSingle(stream.ReadUInt16()); break; case TextureFormat.R24G8_TYPELESS: // not sure if it should be normalized r = Int24ToSingle(stream.ReadUInt24()); g = ByteToSingle(stream.ReadByte()); break; case TextureFormat.R32G32B32_UINT: // not good for visual r = IntToSingle(stream.ReadUInt32()); g = IntToSingle(stream.ReadUInt32()); b = IntToSingle(stream.ReadUInt32()); break; case TextureFormat.D32_S8X24_UINT: r = SingleToSingle(stream.ReadSingle()); g = ByteToSingle((byte)(stream.ReadUInt32() & 0xFF)); break; case TextureFormat.R16G16_UINT: // not good for visual r = UShortToSingle(stream.ReadUInt16()); g = UShortToSingle(stream.ReadUInt16()); break; case TextureFormat.R8G8_UNORM: r = UnormByteToSingle(stream.ReadByte()); g = UnormByteToSingle(stream.ReadByte()); break; case TextureFormat.R32G32F: r = SingleToSingle(stream.ReadSingle()); g = SingleToSingle(stream.ReadSingle()); break; case TextureFormat.R32G32_UINT: // not good for visual r = IntToSingle(stream.ReadUInt32()); g = IntToSingle(stream.ReadUInt32()); break; case TextureFormat.R16G16B16A16_UINT: r = UShortToSingle(stream.ReadUInt16()); g = UShortToSingle(stream.ReadUInt16()); b = UShortToSingle(stream.ReadUInt16()); a = UShortToSingle(stream.ReadUInt16()); break; default: throw new Exception("Unsupported format:" + format.ToString()); } return new PixelColor(r, g, b, a); }