static IEnumerable <Color> GetColorsFromTexture(byte[] tex, Format format) { using (var br = new BinaryReaderX(new MemoryStream(tex))) { var etc1decoder = new ETC1.Decoder(); while (true) { int a = 255, r = 255, g = 255, b = 255; switch (format) { case Format.L8: b = g = r = br.ReadByte(); break; case Format.A8: a = br.ReadByte(); break; case Format.LA44: a = br.ReadNibble() * 17; b = g = r = br.ReadNibble() * 17; break; case Format.LA88: a = br.ReadByte(); b = g = r = br.ReadByte(); break; case Format.HL88: g = br.ReadByte(); r = br.ReadByte(); break; case Format.RGB565: var s = br.ReadUInt16(); b = (s % 32) * 33 / 4; g = (s >> 5) % 64 * 65 / 16; r = (s >> 11) * 33 / 4; break; case Format.RGB888: b = br.ReadByte(); g = br.ReadByte(); r = br.ReadByte(); break; case Format.RGBA5551: var s2 = br.ReadUInt16(); a = (s2 & 1) * 255; b = (s2 >> 1) % 32 * 33 / 4; g = (s2 >> 6) % 32 * 33 / 4; r = (s2 >> 11) % 32 * 33 / 4; break; case Format.RGBA4444: a = br.ReadNibble() * 17; b = br.ReadNibble() * 17; g = br.ReadNibble() * 17; r = br.ReadNibble() * 17; break; case Format.RGBA8888: a = br.ReadByte(); b = br.ReadByte(); g = br.ReadByte(); r = br.ReadByte(); break; case Format.ETC1: case Format.ETC1A4: yield return(etc1decoder.Get(() => { var alpha = (format == Format.ETC1A4) ? br.ReadUInt64() : ulong.MaxValue; return new ETC1.PixelData { Alpha = alpha, Block = br.ReadStruct <ETC1.Block>() }; })); continue; case Format.L4: b = g = r = br.ReadNibble() * 17; break; case Format.A4: a = br.ReadNibble() * 17; break; default: throw new NotSupportedException($"Unknown image format {format}"); } yield return(Color.FromArgb(a, r, g, b)); } } }
static IEnumerable <Color> GetColorsFromTexture(byte[] tex, ImageSettings settings) { var format = settings.Format; using (var br = new BinaryReaderX(new MemoryStream(tex))) { var etc1decoder = new ETC1.Decoder(); Enum.TryParse <DXT.Formats>(format.ToString(), false, out var dxtFormat); var dxtdecoder = new DXT.Decoder(dxtFormat); Enum.TryParse <ATI.Formats>(format.ToString(), false, out var atiFormat); var atidecoder = new ATI.Decoder(atiFormat); while (true) { int a = 255, r = 255, g = 255, b = 255; switch (format) { case Format.L8: b = g = r = br.ReadByte(); break; case Format.A8: a = br.ReadByte(); break; case Format.LA44: a = br.ReadNibble() * 17; b = g = r = br.ReadNibble() * 17; break; case Format.LA88: if (settings.ByteOrder == ByteOrder.LittleEndian) { a = br.ReadByte(); b = g = r = br.ReadByte(); } else { b = g = r = br.ReadByte(); a = br.ReadByte(); } break; case Format.HL88: g = br.ReadByte(); r = br.ReadByte(); break; case Format.RGB565: var s = br.ReadUInt16(); b = (s % 32) * 33 / 4; g = (s >> 5) % 64 * 65 / 16; r = (s >> 11) * 33 / 4; break; case Format.RGB888: b = br.ReadByte(); g = br.ReadByte(); r = br.ReadByte(); break; case Format.RGBA5551: var s2 = br.ReadUInt16(); a = (s2 & 1) * 255; b = (s2 >> 1) % 32 * 33 / 4; g = (s2 >> 6) % 32 * 33 / 4; r = (s2 >> 11) % 32 * 33 / 4; break; case Format.RGBA4444: a = br.ReadNibble() * 17; b = br.ReadNibble() * 17; g = br.ReadNibble() * 17; r = br.ReadNibble() * 17; break; case Format.RGBA8888: if (settings.ByteOrder == ByteOrder.LittleEndian) { a = br.ReadByte(); b = br.ReadByte(); g = br.ReadByte(); r = br.ReadByte(); } else { r = br.ReadByte(); g = br.ReadByte(); b = br.ReadByte(); a = br.ReadByte(); } break; case Format.RGBA1010102: var pack = br.ReadUInt32(); r = (int)((pack >> 22) / 4); g = (int)(((pack >> 12) & 0x3FF) / 4); b = (int)(((pack >> 2) & 0x3FF) / 4); a = (int)((pack & 0x3) * 85); break; case Format.ETC1: case Format.ETC1A4: yield return(etc1decoder.Get(() => { var etc1Alpha = format == Format.ETC1A4 ? br.ReadUInt64() : ulong.MaxValue; return new ETC1.PixelData { Alpha = etc1Alpha, Block = br.ReadStruct <ETC1.Block>() }; })); continue; case Format.DXT1: case Format.DXT3: case Format.DXT5: yield return(dxtdecoder.Get(() => { if (br.BaseStream.Position == br.BaseStream.Length) { return (0, 0); } var dxt5Alpha = format == Format.DXT3 || format == Format.DXT5 ? br.ReadUInt64() : 0; return (dxt5Alpha, br.ReadUInt64()); })); continue; case Format.ATI1L: case Format.ATI1A: case Format.ATI2: yield return(atidecoder.Get(() => { if (br.BaseStream.Position == br.BaseStream.Length) { return (0, 0); } return (br.ReadUInt64(), format == Format.ATI2 ? br.ReadUInt64() : 0); })); continue; case Format.L4: b = g = r = br.ReadNibble() * 17; break; case Format.A4: a = br.ReadNibble() * 17; break; case Format.PVRTC: var bmp = PVRTC.PvrtcDecompress.DecodeRgb4Bpp(tex, settings.Width); for (int y = 0; y < settings.Height; y++) { for (int x = 0; x < settings.Width; x++) { yield return(bmp.GetPixel(x, y)); } } continue; case Format.PVRTCA: bmp = PVRTC.PvrtcDecompress.DecodeRgba4Bpp(tex, settings.Width); for (int y = 0; y < settings.Height; y++) { for (int x = 0; x < settings.Width; x++) { yield return(bmp.GetPixel(x, y)); } } continue; default: throw new NotSupportedException($"Unknown image format {format}"); } yield return(Color.FromArgb(a, r, g, b)); } } }
static IEnumerable <Color> GetColorsFromTexture(byte[] tex, Format format) { using (var br = new BinaryReaderX(new MemoryStream(tex))) { var etc1decoder = new ETC1.Decoder(); Enum.TryParse <DXT.Formats>(format.ToString(), false, out var dxtFormat); var dxtdecoder = new DXT.Decoder(dxtFormat); while (true) { int a = 255, r = 255, g = 255, b = 255; switch (format) { case Format.L8: b = g = r = br.ReadByte(); break; case Format.A8: a = br.ReadByte(); break; case Format.LA44: a = br.ReadNibble() * 17; b = g = r = br.ReadNibble() * 17; break; case Format.LA88: a = br.ReadByte(); b = g = r = br.ReadByte(); break; case Format.HL88: g = br.ReadByte(); r = br.ReadByte(); break; case Format.RGB565: var s = br.ReadUInt16(); b = (s % 32) * 33 / 4; g = (s >> 5) % 64 * 65 / 16; r = (s >> 11) * 33 / 4; break; case Format.RGB888: b = br.ReadByte(); g = br.ReadByte(); r = br.ReadByte(); break; case Format.RGBA5551: var s2 = br.ReadUInt16(); a = (s2 & 1) * 255; b = (s2 >> 1) % 32 * 33 / 4; g = (s2 >> 6) % 32 * 33 / 4; r = (s2 >> 11) % 32 * 33 / 4; break; case Format.RGBA4444: a = br.ReadNibble() * 17; b = br.ReadNibble() * 17; g = br.ReadNibble() * 17; r = br.ReadNibble() * 17; break; case Format.RGBA8888: a = br.ReadByte(); b = br.ReadByte(); g = br.ReadByte(); r = br.ReadByte(); break; case Format.ETC1: case Format.ETC1A4: yield return(etc1decoder.Get(() => { var etc1Alpha = format == Format.ETC1A4 ? br.ReadUInt64() : ulong.MaxValue; return new ETC1.PixelData { Alpha = etc1Alpha, Block = br.ReadStruct <ETC1.Block>() }; })); continue; case Format.DXT1: case Format.DXT3: case Format.DXT5: yield return(dxtdecoder.Get(() => { if (br.BaseStream.Position == br.BaseStream.Length) { return (0, 0); } var dxt5Alpha = format == Format.DXT3 || format == Format.DXT5 ? br.ReadUInt64() : 0; return (dxt5Alpha, br.ReadUInt64()); })); continue; case Format.L4: b = g = r = br.ReadNibble() * 17; break; case Format.A4: a = br.ReadNibble() * 17; break; default: throw new NotSupportedException($"Unknown image format {format}"); } yield return(Color.FromArgb(a, r, g, b)); } } }