public void SetData(byte[] rawData, PixelEncoding pixelEnc, ColorFormat format, Size tileSize) { if (this.width == 0 || this.height == 0) { throw new ArgumentOutOfRangeException("Width and Height have not been specified."); } this.pixelEnc = pixelEnc; this.format = format; this.tileSize = tileSize; // First convert to 24bpp index + 8 bits alpha if it's indexed or ARGB32 otherwise. // normalizeData contains information about 1 pixel (index or color) this.original = new uint[rawData.Length * 8 / this.Format.Bpp()]; int rawPos = 0; for (int i = 0; i < this.original.Length; i++) { uint info = rawData.GetBits(ref rawPos, this.Format.Bpp()); // Get pixel info from raw data this.original[i] = this.format.UnpackColor(info); // Get color from pixel info (unpack info) } // Then convert to lineal pixel encoding this.data = new uint[this.width * this.height]; this.pixelEnc.Codec(this.original, this.data, true, this.width, this.height, this.tileSize); }
// By PleoNeX public static int GetIndex(PixelEncoding pxEnc, int x, int y, int width, int height, Size tileSize) { if (pxEnc == PixelEncoding.Lineal) { return(y * width + x); } int tileLength = tileSize.Width * tileSize.Height; int numTilesX = width / tileSize.Width; int numTilesY = height / tileSize.Height; // Get lineal index Point pixelPos = new Point(x % tileSize.Width, y % tileSize.Height); // Pos. pixel in tile Point tilePos = new Point(x / tileSize.Width, y / tileSize.Height); // Pos. tile in image int index = 0; if (pxEnc == PixelEncoding.HorizontalTiles) { index = tilePos.Y * numTilesX * tileLength + tilePos.X * tileLength; // Absolute tile pos. } else if (pxEnc == PixelEncoding.VerticalTiles) { index = tilePos.X * numTilesY * tileLength + tilePos.Y * tileLength; // Absolute tile pos. } index += pixelPos.Y * tileSize.Width + pixelPos.X; // Add pos. of pixel inside tile return(index); }
public Image() { this.data = null; this.original = null; this.format = ColorFormat.Unknown; this.pixelEnc = PixelEncoding.Unknown; this.tileSize = new Size(8, 8); this.width = 0; this.height = 0; }
public static void Codec <T>(this PixelEncoding pxEnc, T[] dataIn, T[] dataOut, bool decoding, int width, int height, Size tileSize) { if (pxEnc != PixelEncoding.Lineal && pxEnc != PixelEncoding.HorizontalTiles && pxEnc != PixelEncoding.VerticalTiles) { throw new NotSupportedException(); } if (dataIn == null || dataOut == null || dataIn.Length > dataOut.Length) { throw new ArgumentNullException(); } if ((width % tileSize.Width != 0) && (pxEnc == PixelEncoding.HorizontalTiles || pxEnc == PixelEncoding.VerticalTiles)) { throw new FormatException("Width must be a multiple of tile width to use Tiled pixel encoding."); } // Little trick to use the same equations if (pxEnc == PixelEncoding.Lineal) { tileSize = new Size(width, height); } for (int linealIndex = 0; linealIndex < dataOut.Length; linealIndex++) { int tiledIndex = pxEnc.GetIndex(linealIndex % width, linealIndex / width, width, height, tileSize); if (decoding) { // As the new data is lineal, and in the last row of tiles in the dataIn can be incompleted // the output array can contains null pixels in the middle of the array. if (tiledIndex >= dataIn.Length) { dataOut[linealIndex] = default(T); // Null pixel } else { dataOut[linealIndex] = dataIn[tiledIndex]; } } else { // As this index will increment lineally, we can stop, there isn't more data to code if (linealIndex >= dataIn.Length) { break; } dataOut[tiledIndex] = dataIn[linealIndex]; } } }
private Image(Image img, uint[] data, int width, int height) { this.original = data; this.width = width; this.height = height; this.format = img.Format; this.pixelEnc = img.PixelEncoding; this.tileSize = img.TileSize; this.data = new uint[data.Length]; this.pixelEnc.Codec(this.original, this.data, true, this.width, this.height, this.tileSize); }
public static bool IsTiled(this PixelEncoding enc) { switch (enc) { case PixelEncoding.HorizontalTiles: case PixelEncoding.VerticalTiles: return(true); case PixelEncoding.Lineal: return(false); default: throw new FormatException(); } }
public void SetData(Pixel[] pixels, PixelEncoding pixelEnc, ColorFormat format, Size tileSize) { if (this.width == 0 || this.height == 0) { throw new ArgumentOutOfRangeException("Width and Height have not been specified."); } this.pixelEnc = pixelEnc; this.format = format; this.tileSize = tileSize; this.original = new uint[pixels.Length]; for (int i = 0; i < pixels.Length; i++) { this.original[i] = (uint)(pixels[i].Alpha << 24) | (uint)pixels[i].Info; } this.data = new uint[this.width * this.height]; this.pixelEnc.Codec(this.original, this.data, true, this.width, this.height, this.tileSize); }
public static WiiImage Create(EndianReader stream) { byte id = stream.ReadByte(); if (id != 1 && id != 2) { throw new FormatException(); // ID byte } WiiImage image = new WiiImage(); image.BitsPerPixel = stream.ReadByte(); // If this isn't 4... I think we're f****d. stream.Position += 5; // 5 bytes of who knows what image.Width = stream.ReadUInt16(); image.Height = stream.ReadUInt16(); stream.ReadByte(); // Dunno... stream.PadReadTo(0x20); image.Bitmap = PixelEncoding.GetEncoding <CMPR>().DecodeImage(stream.Base, image.Width, image.Height); return(image); }
public static NgcImage Create(EndianReader stream) { NgcImage image = new NgcImage(); image.BitsPerPixel = stream.ReadByte(); // If this isn't 4... I think we're f****d. stream.Position = 0x0A; image.Width = (int)Math.Pow(2, stream.ReadByte()); image.Height = (int)Math.Pow(2, stream.ReadByte()); stream.PadReadTo(0x20); Bitmap bitmap = PixelEncoding.GetEncoding <CMPR>().DecodeImage(stream.Base, (uint)image.Width, (uint)image.Height); image.Bitmap = new Bitmap(image.Width, image.Height); for (int x = 0; x < image.Width; x++) { for (int y = 0; y < image.Height; y++) { image.Bitmap.SetPixel(x, y, bitmap.GetPixel(x, image.Height - y - 1)); } } return(image); }
public Txm(Stream stream, Stream data) : this() { EndianReader reader = new EndianReader(stream, Endianness.BigEndian); if (reader.ReadUInt32() != Magic) { throw new FormatException(); } uint filesize = reader.ReadUInt32(); Unknown = reader.ReadUInt32(); uint files = reader.ReadUInt32(); ulong zero = reader.ReadUInt64(); if (zero != 0) { throw new FormatException(); } Dictionary <Image, long> nameoffsets = new Dictionary <Image, long>(); for (uint i = 0; i < files; i++) { Image image = new Image(); image.Width = reader.ReadUInt32(); image.Height = reader.ReadUInt32(); image.Unknown1 = reader.ReadUInt32(); image.Unknown2 = reader.ReadByte(); image.Unknown3 = reader.ReadByte(); ushort encoding = reader.ReadUInt16(); if (encoding == 0xAAE4) // PS3 ToGf { if (image.Unknown2 == 0x88 || image.Unknown2 == 0xa8) { image.PrimaryEncoding = new DXT5(); } else if (image.Unknown2 == 0xa5) { image.PrimaryEncoding = new ARGB(); } else if (image.Unknown2 == 0x85) { image.PrimaryEncoding = new TiledARGB(); } else if (image.Unknown2 == 0xa6 || image.Unknown2 == 0x86) { image.PrimaryEncoding = new DXT1(); } else { Console.WriteLine("WARNING: Unknown PS3 encoding 0x" + image.Unknown2.ToString("x")); image.PrimaryEncoding = new NullEncoding(); } } else { image.PrimaryEncoding = PixelEncoding.GetEncoding(encoding); } nameoffsets[image] = reader.Position + reader.ReadUInt32(); uint offset1 = reader.ReadUInt32(); uint offset2 = reader.ReadUInt32(); image.PrimaryData = new Substream(data, offset1, image.PrimaryLength); if (offset2 > 0) // Best hack I have for determining whether there's a secondary image or not { image.SecondaryData = new Substream(data, offset2, image.SecondaryLength); } Images.Add(image); } foreach (var offset in nameoffsets) { stream.Position = offset.Value; offset.Key.Name = stream.ReadCString(); } }
public void SetData(byte[] rawData, PixelEncoding pixelEnc, ColorFormat format, Size tileSize) { if (this.width == 0 || this.height == 0) throw new ArgumentOutOfRangeException("Width and Height have not been specified."); this.pixelEnc = pixelEnc; this.format = format; this.tileSize = tileSize; // First convert to 24bpp index + 8 bits alpha if it's indexed or ARGB32 otherwise. // normalizeData contains information about 1 pixel (index or color) this.original = new uint[rawData.Length * 8 / this.Format.Bpp()]; int rawPos = 0; for (int i = 0; i < this.original.Length; i++) { uint info = rawData.GetBits(ref rawPos, this.Format.Bpp()); // Get pixel info from raw data this.original[i] = this.format.UnpackColor(info); // Get color from pixel info (unpack info) } // Then convert to lineal pixel encoding this.data = new uint[this.width * this.height]; this.pixelEnc.Codec(this.original, this.data, true, this.width, this.height, this.tileSize); }
public void SetData(Pixel[] pixels, PixelEncoding pixelEnc, ColorFormat format, Size tileSize) { if (this.width == 0 || this.height == 0) throw new ArgumentOutOfRangeException("Width and Height have not been specified."); this.pixelEnc = pixelEnc; this.format = format; this.tileSize = tileSize; this.original = new uint[pixels.Length]; for (int i = 0; i < pixels.Length; i++) this.original[i] = (uint)(pixels[i].Alpha << 24) | (uint)pixels[i].Info; this.data = new uint[this.width * this.height]; this.pixelEnc.Codec(this.original, this.data, true, this.width, this.height, this.tileSize); }
/// <summary> /// Initializes an Instance of ImagePixelChannel /// </summary> /// <param name="firstBit"></param> /// <param name="numBits"></param> /// <param name="encoding"></param> public ImagePixelChannel(int firstBit, int numBits, PixelEncoding encoding) { FirstBit = firstBit; NumBits = numBits; Encoding = encoding; }
private static void OperationPng2Tex() { string filename = ConsolePath("Full path to tex or txm/txv or png file..?"); if (filename.IsEmpty()) { return; } if (Path.GetExtension(filename).ToLower() == ".txm" || Path.GetExtension(filename).ToLower() == ".txv") { filename = filename.Substring(0, filename.Length - 4); } else if (Path.GetExtension(filename).ToLower() != ".tex") { filename = Path.GetDirectoryName(filename); if (filename.EndsWith(".ext")) { filename = filename.Substring(0, filename.Length - 4); } } DelayedStreamCache streams = new DelayedStreamCache(); Txm tex = OpenTex(filename, streams); Stream txmstream; Stream txvstream; if (File.Exists(filename)) { txmstream = new TemporaryStream(); txvstream = new TemporaryStream(); } else { txmstream = new FileStream(filename + ".txm.new", FileMode.Create); txvstream = new FileStream(filename + ".txv.new", FileMode.Create); } streams.AddStream(txmstream); streams.AddStream(txvstream); string[] files = Directory.GetFiles(filename + ".ext"); files = files.OrderBy(f => f).ToArray(); // Want to make sure the .dat files come before the pngs (hacky, but meh). foreach (string file in files) { string name = Path.GetFileName(file); string basename = Path.GetFileNameWithoutExtension(name); string extension = Path.GetExtension(name); Txm.Image image = tex.Images.FirstOrDefault(i => i.Name == basename); if (image == null) { if (extension != ".dat" && extension != ".png") { continue; } image = new Txm.Image(); image.Name = basename; image.PrimaryEncoding = PixelEncoding.GetEncoding <CI8>(); image.SecondaryData = new MemoryStream(); image.Unknown1 = 1; image.Unknown2 = 2 << 4; image.Unknown3 = 1; tex.Images.Add(image); } Stream stream = new FileStream(file, FileMode.Open); if (extension == ".dat") { image.SecondaryData = new MemoryStream((int)stream.Length); Util.StreamCopy(image.SecondaryData, stream); } else if (extension == ".png") { Bitmap bitmap = new Bitmap(stream); stream.Close(); stream = new MemoryStream(); if (image.SecondaryData is Substream || image.SecondaryData == null) { image.SecondaryData = new MemoryStream(); } image.SecondaryData.Position = 0; try { image.PrimaryEncoding.EncodeImage(stream, bitmap, image.SecondaryData, image.Unknown2 >> 4); } catch (NotImplementedException ex) { if (image.PrimaryEncoding.ID == 0xAAE4) { image.PrimaryEncoding = new ARGB(); image.Unknown1 = 5; image.Unknown2 = 0xa5; image.Unknown3 = 4; } else { image.PrimaryEncoding = PixelEncoding.GetEncoding <CI8>(); image.Unknown1 = 1; image.Unknown2 = 2 << 4; image.Unknown3 = 1; } try { image.PrimaryEncoding.EncodeImage(stream, bitmap, image.SecondaryData, image.Unknown2 >> 4); } catch { throw ex; } } image.Width = (uint)bitmap.Width; image.Height = (uint)bitmap.Height; image.PrimaryData = stream; } streams.AddStream(stream); } tex.Save(txmstream, txvstream); if (File.Exists(filename)) { Stream texstream = new FileStream(filename + ".new", FileMode.Create); streams.AddStream(texstream); FPS4Base fps = new FPS4Base(); fps.DataOffset = 0x60; fps.BlockSize = 0x0C; fps.Files = 3; fps.Flags = FPS4Base.NodeFlags.SectionSize | FPS4Base.NodeFlags.Filesize | FPS4Base.NodeFlags.Offset; fps.Type = new byte[] { 0x74, 0x78, 0x6D, 0x76 }; // "txmv" fps.TypeOffset = 0x40; uint txmlen = (uint)Util.RoundUp(txmstream.Length, 0x20); uint txvlen = (uint)Util.RoundUp(txvstream.Length, 0x20); fps.Nodes.Add(new FPS4Base.Node(0x60, txmlen, (uint)txmstream.Length, "", 0, 0, txmstream)); fps.Nodes.Add(new FPS4Base.Node(0x60 + txmlen, txvlen, (uint)txvstream.Length, "", 0, 0, txvstream)); fps.Nodes.Add(new FPS4Base.Node(0x60 + txmlen + txvlen, 0, 0, "", 0, 0, null)); fps.Save(texstream); } streams.Dispose(); }
public override void Damage(int x, int y, int w, int h, PixelEncoding encoding, byte[] data) { if (!NewBufferSize && Pixels == null) { return; } if (NewBufferSize) { if (!IsPopup) { Compositor.TriggerWindowResized((UnityWindow)this); } var ss = new Vector3(BufferSize.W / 100f, BufferSize.H / 100f, 1); SurfaceCorner.transform.localPosition = new Vector3(-ss.x / 2, ss.y / 2, 0); Surface.transform.localPosition = new Vector3(ss.x / 2, -ss.y / 2, 0); Surface.transform.localScale = ss; UpdateWindowSize(ss); NewBufferSize = false; SurfaceTexture = new Texture2D(w, h, TextureFormat.RGB24, false); SurfaceRenderer.material.SetTexture("_MainTex", SurfaceTexture); if (x != 0 || y != 0 || w != BufferSize.W || h != BufferSize.H) { throw new Exception("Damage buffer must be a full refresh after buffer size update"); } SurfaceTexture.LoadRawTextureData(data); SurfaceTexture.Apply(); Pixels = new byte[w * h * 3]; Array.Copy(data, 0, Pixels, 0, w * h * 3); } else { if (x == 0 && y == 0 && w == BufferSize.W && h == BufferSize.H) { Array.Copy(data, 0, Pixels, 0, w * h * 3); } else if (w == BufferSize.W) { Array.Copy(data, 0, Pixels, y * BufferSize.W * 3, w * h * 3); } else { for (var i = 0; i < h; ++i) { Array.Copy(data, i * w * 3, Pixels, (y + i) * BufferSize.W * 3 + x * 3, w * 3); } } SurfaceTexture.LoadRawTextureData(Pixels); SurfaceTexture.Apply(); } if (!Initialized) { Window.SetActive(true); Initialized = true; if (!IsPopup) { Compositor.TriggerWindowShown((UnityWindow)this); } } }
public Pixel[] GetPixels(PixelEncoding enc) { Pixel[] encoded = new Pixel[this.Width * this.Height]; enc.Codec <Pixel>(this.Pixels, encoded, false, this.Width, this.Height, this.TileSize); return(encoded); }
public static extern void SendFrame(IntPtr sender, IntPtr data, int width, int height, PixelEncoding fourCC);
public Image(Pixel[] pixels, int width, int height, PixelEncoding pxEnc, ColorFormat format, Size tileSize) { this.width = width; this.height = height; this.SetData(pixels, pxEnc, format, tileSize); }
public void SetData(byte[] rawData, PixelEncoding pixelEnc, ColorFormat format) { this.SetData(rawData, pixelEnc, format, new Size(8, 8)); }
public Pixel[] GetPixels(PixelEncoding enc) { Pixel[] encoded = new Pixel[this.Width * this.Height]; enc.Codec<Pixel>(this.Pixels, encoded, false, this.Width, this.Height, this.TileSize); return encoded; }