public MK64Image(TKMK00Block tkmk, string name) { TextureOffset = -1; TextureEncoding = MK64ImageEncoding.TKMK00; TextureBlockOffset = 0; PaletteOffset = new List <int>(); PaletteEncoding = new List <MK64ImageEncoding>(); PaletteBlockOffset = new List <int>(); PaletteColorCount = new List <int>(); PaletteColorOffset = new List <int>(); TKMKLength = tkmk.RawDataSize; TKMKAlphaColor = tkmk.ImageAlphaColor; Format = Texture.ImageFormat.RGBA; PixelSize = Texture.PixelInfo.Size_16b; Width = tkmk.Image.Width; Height = tkmk.Image.Height; IsOriginalImage = false; if (string.IsNullOrWhiteSpace(name)) { ImageName = TextureOffset.ToString("X"); } else { ImageName = name; } TKMKReference = tkmk; IsValidImage = (tkmk != null); }
public MK64Image(XElement xml, Palette existingPalette = null) { TextureOffset = int.Parse(xml.Attribute(TEXTURE_OFFSET).Value.ToString()); TextureEncoding = (MK64ImageEncoding)Enum.Parse(typeof(MK64ImageEncoding), xml.Attribute(TEXTURE_ENCODING).Value.ToString()); TextureBlockOffset = int.Parse(xml.Attribute(TEXTURE_BLOCK_OFFSET).Value.ToString()); XElement palettesXML = xml.Element(PALETTES); PaletteOffset = new List <int>(); PaletteEncoding = new List <MK64ImageEncoding>(); PaletteBlockOffset = new List <int>(); PaletteColorCount = new List <int>(); PaletteColorOffset = new List <int>(); foreach (XElement paletteXml in palettesXML.Elements()) { PaletteOffset.Add(int.Parse(paletteXml.Attribute(PALETTE_OFFSET).Value.ToString())); PaletteEncoding.Add((MK64ImageEncoding)Enum.Parse(typeof(MK64ImageEncoding), paletteXml.Attribute(PALETTE_ENCODING).Value.ToString())); PaletteBlockOffset.Add(int.Parse(paletteXml.Attribute(PALETTE_BLOCK_OFFSET).Value.ToString())); PaletteColorCount.Add(int.Parse(paletteXml.Attribute(PALETTE_COLOR_COUNT).Value.ToString())); PaletteColorOffset.Add(int.Parse(paletteXml.Attribute(PALETTE_COLOR_OFFSET).Value.ToString())); } TKMKLength = int.Parse(xml.Attribute(TKMK_LENGTH).Value.ToString()); TKMKAlphaColor = ushort.Parse(xml.Attribute(TKMK_ALPHA_COLOR).Value.ToString()); Format = (Texture.ImageFormat)Enum.Parse(typeof(Texture.ImageFormat), xml.Attribute(FORMAT).Value.ToString()); PixelSize = (Texture.PixelInfo)Enum.Parse(typeof(Texture.PixelInfo), xml.Attribute(PIXEL_SIZE).Value.ToString()); Width = int.Parse(xml.Attribute(WIDTH).Value.ToString()); Height = int.Parse(xml.Attribute(HEIGHT).Value.ToString()); IsOriginalImage = bool.Parse(xml.Attribute(IS_ORIGINAL_IMAGE).Value.ToString()); ImageName = xml.Attribute(IMAGE_NAME).Value.ToString(); if (xml.Element(typeof(TKMK00Block).ToString()) != null) { //load TKMK00 reference here if (!FindExistingTKMK00()) { TKMKReference = new TKMK00Block(xml.Element(typeof(TKMK00Block).ToString())); } } else if (xml.Element(F3DEXImage.F3DEXIMAGE) != null) { //load f3deximage reference F3DEXImage newImage = new F3DEXImage(xml.Element(F3DEXImage.F3DEXIMAGE), existingPalette); if (!FindExistingF3DEXImage(newImage.Texture, newImage.BasePalettes)) { ImageReference = newImage; } } else { LoadImageData(); } }
private void LoadImageData(byte[] rawData = null) { IsValidImage = false; //Check that the format is correct (ex. CI & palette offsets are valid) int maxTextureLocation = (rawData != null ? rawData.Length - 1 : RomProject.Instance.Files[0].FileLength - 1); if (TextureOffset < 0 || TextureOffset > maxTextureLocation || (Format == Texture.ImageFormat.CI && PaletteOffset.Count == 0)) { return; } if (!TextureConversion.IsValidFormatCombo(Format, PixelSize)) { return; } //Try to load the texture, palette & image here N64DataElement element; Palette paletteRef = null; List <Palette> paletteRefs = new List <Palette>(); if (Format == Texture.ImageFormat.CI) //If CI format, we need to get the palette too { for (int i = 0; i < PaletteOffset.Count; i++) { paletteRef = null; if (RomProject.Instance.Files[0].HasElementExactlyAt(PaletteOffset[i], out element) && element.FileOffset == PaletteOffset[i] && !(element is UnknownData)) { switch (PaletteEncoding[i]) { case MK64ImageEncoding.Raw: //Needs to be a raw palette if (!(element is Palette)) { return; } paletteRef = (Palette)element; break; case MK64ImageEncoding.MIO0: //Needs to be a mio0 block if (!(element is MIO0Block)) { return; } MIO0Block block = (MIO0Block)element; //System.IO.File.WriteAllBytes("test.bin",block.DecodedData); //now to search inside if (block.Elements.FirstOrDefault(e => e.FileOffset == PaletteBlockOffset[i]) != null) { N64DataElement paletteEl = block.Elements.First(e => e.FileOffset == PaletteBlockOffset[i]); if (paletteEl is Palette) { paletteRef = (Palette)paletteEl; } } else { //Create the palette! byte[] data = new byte[PaletteColorCount[i] * 2]; Array.Copy(block.DecodedData, PaletteBlockOffset[i], data, 0, data.Length); Palette pal = new Palette(PaletteBlockOffset[i], data); if (block.AddElement(pal)) { paletteRef = pal; } } break; } } else { //AVOID THIS AS MUCH AS POSSIBLE, IT WILL SLOW EVERYTHING DOWN TREMENDOUSLY!! if (rawData == null) { rawData = RomProject.Instance.Files[0].GetAsBytes(); } //Create the palette! switch (PaletteEncoding[i]) { case MK64ImageEncoding.Raw: //Create the palette! byte[] data = new byte[PaletteColorCount[i] * 2]; Array.Copy(rawData, PaletteOffset[i], data, 0, data.Length); Palette pal = new Palette(PaletteOffset[i], data); if (RomProject.Instance.Files[0].AddElement(pal)) { paletteRef = pal; } break; case MK64ImageEncoding.MIO0: //Create the MIO0 block! MIO0Block block = MIO0Block.ReadMIO0BlockFrom(rawData, PaletteOffset[i]); //System.IO.File.WriteAllBytes("test.bin",block.DecodedData); if (RomProject.Instance.Files[0].AddElement(block)) { //Create the palette in the MIO0 block! byte[] mioData = new byte[PaletteColorCount[i] * 2]; Array.Copy(block.DecodedData, PaletteBlockOffset[i], mioData, 0, mioData.Length); Palette palette = new Palette(PaletteBlockOffset[i], mioData); if (block.AddElement(palette)) { paletteRef = palette; } else { throw new Exception(); } } break; } } paletteRefs.Add(paletteRef); } } Texture textureRef = null; TKMK00Block tkmkRef = null; if (RomProject.Instance.Files[0].HasElementExactlyAt(TextureOffset, out element) && element.FileOffset == TextureOffset && !(element is UnknownData)) { switch (TextureEncoding) { case MK64ImageEncoding.Raw: //Needs to be a raw texture if (!(element is Texture)) { return; } textureRef = (Texture)element; break; case MK64ImageEncoding.MIO0: //Needs to be a mio0 block if (!(element is MIO0Block)) { return; } MIO0Block block = (MIO0Block)element; //now to search inside if (block.Elements.FirstOrDefault(e => e.FileOffset == TextureBlockOffset) != null) { N64DataElement textureEl = block.Elements.First(e => e.FileOffset == TextureBlockOffset); if (textureEl is Texture) { textureRef = (Texture)textureEl; } } else { //Create the texture here //Create the palette! double byteSize = 1; switch (PixelSize) { case Texture.PixelInfo.Size_4b: byteSize = 0.5; break; case Texture.PixelInfo.Size_16b: byteSize = 2; break; case Texture.PixelInfo.Size_32b: byteSize = 4; break; } byte[] data = new byte[(int)Math.Round(Width * Height * byteSize)]; Array.Copy(block.DecodedData, TextureBlockOffset, data, 0, data.Length); Texture text = new Texture(TextureBlockOffset, data, Format, PixelSize, Width, Height); if (block.AddElement(text)) { textureRef = text; } } break; case MK64ImageEncoding.TKMK00: //Needs to be a tkmk00 block if (!(element is TKMK00Block)) { return; } tkmkRef = (TKMK00Block)element; break; } } else //NEED TO CREATE IT HERE! { //AVOID THIS AS MUCH AS POSSIBLE, IT WILL SLOW EVERYTHING DOWN TREMENDOUSLY!! if (rawData == null) { rawData = RomProject.Instance.Files[0].GetAsBytes(); } switch (TextureEncoding) { case MK64ImageEncoding.Raw: //Just create the new texture image! double byteSize = 1; switch (PixelSize) { case Texture.PixelInfo.Size_4b: byteSize = 0.5; break; case Texture.PixelInfo.Size_16b: byteSize = 2; break; case Texture.PixelInfo.Size_32b: byteSize = 4; break; } byte[] data = new byte[(int)Math.Round(Width * Height * byteSize)]; Array.Copy(rawData, TextureOffset, data, 0, data.Length); Texture texture = new Texture(TextureOffset, data, Format, PixelSize, Width, Height); //Add to the rom project if (RomProject.Instance.Files[0].AddElement(texture)) { textureRef = texture; } break; case MK64ImageEncoding.MIO0: //Since no MIO0 block was found, it needs to be created MIO0Block block = MIO0Block.ReadMIO0BlockFrom(rawData, TextureOffset); if (RomProject.Instance.Files[0].AddElement(block)) { double ByteSize = 1; switch (PixelSize) { case Texture.PixelInfo.Size_4b: ByteSize = 0.5; break; case Texture.PixelInfo.Size_16b: ByteSize = 2; break; case Texture.PixelInfo.Size_32b: ByteSize = 4; break; } byte[] textData = new byte[(int)Math.Round(Width * Height * ByteSize)]; Array.Copy(block.DecodedData, TextureBlockOffset, textData, 0, textData.Length); Texture text = new Texture(TextureBlockOffset, textData, Format, PixelSize, Width, Height); if (block.AddElement(text)) { textureRef = text; } } break; case MK64ImageEncoding.TKMK00: //Need to create the TKMK00Block, and it'll handle the rest TKMK00Block tkmk; byte[] bytes = new byte[TKMKLength]; Array.Copy(rawData, TextureOffset, bytes, 0, TKMKLength); tkmk = new TKMK00Block(TextureOffset, bytes, TKMKAlphaColor); if (RomProject.Instance.Files[0].AddElement(tkmk)) { tkmkRef = tkmk; } break; } } if ((textureRef == null && tkmkRef == null) || (Format == Texture.ImageFormat.CI && (paletteRefs.Count == 0 || paletteRefs.Contains(null)))) { return; } //Test to make sure the texture matches the format and such if (textureRef != null && Format != textureRef.Format) { return; } //Successfully found the palette, set the references TKMKReference = tkmkRef; if (TextureEncoding == MK64ImageEncoding.TKMK00) { IsValidImage = (TKMKReference != null); return; } F3DEXImage image = new F3DEXImage(textureRef, paletteRefs); ImageReference = image; IsValidImage = image.ValidImage; }