Ejemplo n.º 1
0
        public IMGC(Stream input)
        {
            using (var br = new BinaryReaderX(input, true))
            {
                //Header
                header = br.ReadType <IMGCHeader>();
                if (header.imageFormat == 28 && header.bitDepth == 8)
                {
                    editMode           = true;
                    header.imageFormat = 29;
                }

                //get tile table
                br.BaseStream.Position = header.tableDataOffset;
                var tableC = br.ReadBytes(header.tableSize1);
                tableComp = (CompressionMethod)(tableC[0] & 0x7);
                byte[] table = Compressor.Decompress(new MemoryStream(tableC));

                //get image data
                br.BaseStream.Position = header.tableDataOffset + header.tableSize2;
                var texC = br.ReadBytes(header.imgDataSize);
                picComp = (CompressionMethod)(texC[0] & 0x7);
                byte[] tex = Compressor.Decompress(new MemoryStream(texC));

                //order pic blocks by table
                byte[] pic = Order(new MemoryStream(table), new MemoryStream(tex));

                //return finished image
                settings = new ImageSettings(Support.Format[header.imageFormat], header.width, header.height)
                {
                    Swizzle = new ImgcSwizzle(header.width, header.height)
                };
                Image = Kolors.Load(pic, settings);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="input"></param>
        public BTX(Stream input)
        {
            using (var br = new BinaryReaderX(input, true))
            {
                // Header
                Header = br.ReadType <FileHeader>();
                br.SeekAlignment();
                FileName = br.ReadCStringASCII();

                // Setup
                var dataLength        = Header.Width * Header.Height;
                var paletteDataLength = Header.ColorCount * 4;

                // Image
                br.BaseStream.Position = Header.ImageOffset;
                var texture = br.ReadBytes(dataLength);

                // Palette
                if (Header.Format == ImageFormat.Palette_8)
                {
                    br.BaseStream.Position = Header.PaletteOffset;
                    var palette = br.ReadBytes(paletteDataLength);

                    var settings = new IndexedImageSettings(IndexEncodings[(int)Header.Format], PaletteEncodings[(int)Header.Format], Header.Width, Header.Height);
                    var data     = Kolors.Load(texture, palette, settings);
                    Texture           = data.image;
                    Palette           = data.palette;
                    FormatName        = IndexEncodings[(int)Header.Format].FormatName;
                    PaletteFormatName = PaletteEncodings[(int)Header.Format].FormatName;
                    HasPalette        = true;
                }
                else
                {
                    var settings = new ImageSettings(Encodings[(int)Header.Format], Header.Width, Header.Height);
                    Texture    = Kolors.Load(texture, settings);
                    FormatName = Encodings[(int)Header.Format].FormatName;
                }
            }
        }
Ejemplo n.º 3
0
        public TEX(Stream input)
        {
            using (var br = new BinaryReaderX(input))
            {
                // Set endianess
                if (br.PeekString() == "\0XET")
                {
                    br.ByteOrder = ByteOrder = ByteOrder.BigEndian;
                }

                // Header
                Header     = br.ReadType <FileHeader>();
                HeaderInfo = new FileHeaderInfo
                {
                    // Block 1
                    Version           = (Version)(Header.Block1 & 0xFFF),
                    Unknown1          = (int)((Header.Block1 >> 12) & 0xFFF),
                    Unused1           = (int)((Header.Block1 >> 24) & 0xF),
                    AlphaChannelFlags = (AlphaChannelFlags)((Header.Block1 >> 28) & 0xF),
                    // Block 2
                    MipMapCount = (int)(Header.Block2 & 0x3F),
                    Width       = (int)((Header.Block2 >> 6) & 0x1FFF),
                    Height      = Math.Max((int)((Header.Block2 >> 19) & 0x1FFF), MinHeight),
                    // Block 3
                    Unknown2 = (int)(Header.Block3 & 0xFF),
                    Format   = (byte)((Header.Block3 >> 8) & 0xFF),
                    Unknown3 = (int)((Header.Block3 >> 16) & 0xFFFF)
                };

                if (HeaderInfo.Version == Version._Switchv1 && !SwitchFormats.ContainsKey(HeaderInfo.Format))
                {
                    throw new InvalidOperationException($"Switch texture format 0x{HeaderInfo.Format.ToString("X2")} is not implemented.");
                }
                else if (!Formats.ContainsKey(HeaderInfo.Format))
                {
                    throw new InvalidOperationException($"Texture format 0x{HeaderInfo.Format.ToString("X2")} is not implemented.");
                }

                // TODO: Consider whether the following settings make more sense if conditioned by the ByteOrder (or Platform)
                //var format = HeaderInfo.Format.ToString().StartsWith("DXT1") ? Format.DXT1 : HeaderInfo.Format.ToString().StartsWith("DXT5") ? Format.DXT5 : HeaderInfo.Format;
                var encoding = (HeaderInfo.Version == Version._Switchv1) ? SwitchFormats[HeaderInfo.Format] : Formats[HeaderInfo.Format];

                List <int> mipMaps = null;
                if (HeaderInfo.Version == Version._Switchv1)
                {
                    var texOverallSize = br.ReadInt32();
                    if (texOverallSize > br.BaseStream.Length)
                    {
                        br.BaseStream.Position -= 4;
                        SwitchUnknownData       = br.ReadBytes(0x6C);
                        texOverallSize          = br.ReadInt32();
                        HeaderInfo.MipMapCount++;
                    }
                    mipMaps = br.ReadMultiple <int>(HeaderInfo.MipMapCount);
                }
                else if (HeaderInfo.Version != Version._3DSv1)
                {
                    mipMaps = br.ReadMultiple <int>(HeaderInfo.MipMapCount);
                }

                for (var i = 0; i < mipMaps.Count; i++)
                {
                    var texDataSize = 0;
                    if (SwitchUnknownData != null)
                    {
                        if (i + 1 == HeaderInfo.MipMapCount)
                        {
                            continue;
                        }
                        texDataSize = mipMaps[i + 1] - mipMaps[i];
                    }
                    else if (HeaderInfo.Version != Version._3DSv1)
                    {
                        texDataSize = (i + 1 < HeaderInfo.MipMapCount ? mipMaps[i + 1] : (int)br.BaseStream.Length) - mipMaps[i];
                    }
                    else
                    {
                        texDataSize = Formats[HeaderInfo.Format].BitDepth * (HeaderInfo.Width >> i) * (HeaderInfo.Height >> i) / 8;
                    }

                    Settings = new ImageSettings(encoding, Math.Max(HeaderInfo.Width >> i, 2), Math.Max(HeaderInfo.Height >> i, 2));

                    //Set possible Swizzles
                    if (HeaderInfo.Version == Version._3DSv1 || HeaderInfo.Version == Version._3DSv2 || HeaderInfo.Version == Version._3DSv3)
                    {
                        Settings.Swizzle = new CTRSwizzle(Settings.Width, Settings.Height, CtrTransformation.None, true);
                    }
                    else if (HeaderInfo.Version == Version._Switchv1)
                    {
                        Settings.Swizzle = new SwitchSwizzle(Settings.Width, Settings.Height, Settings.Encoding.BitDepth, GetSwitchSwizzleFormat(Settings.Encoding.FormatName), true);
                    }
                    else if (Settings.Encoding.FormatName.Contains("DXT"))
                    {
                        Settings.Swizzle = new BCSwizzle(Settings.Width, Settings.Height);
                    }

                    //Set possible pixel shaders
                    if ((Format)HeaderInfo.Format == Format.DXT5_B)
                    {
                        Settings.PixelShader = ToNoAlpha;
                    }
                    else if ((Format)HeaderInfo.Format == Format.DXT5_YCbCr)
                    {
                        Settings.PixelShader = ToProperColors;
                    }

                    EncodingInfo info = null;
                    if (HeaderInfo.Version == Version._3DSv1 || HeaderInfo.Version == Version._3DSv2 ||
                        HeaderInfo.Version == Version._3DSv3)
                    {
                        info = EncodingInfos.First(x => x.EncodingIndex == HeaderInfo.Format);
                    }
                    else if (HeaderInfo.Version == Version._Switchv1)
                    {
                        info = SwitchEncodingInfos.First(x => x.EncodingIndex == HeaderInfo.Format);
                    }

                    if (i == 0)
                    {
                        Bitmaps.Add(new BitmapInfo(Kolors.Load(br.ReadBytes(texDataSize), Settings), info));
                    }
                    else
                    {
                        Bitmaps[0].MipMaps.Add(Kolors.Load(br.ReadBytes(texDataSize), Settings));
                    }
                }

                if (SwitchUnknownData != null)
                {
                    SwitchOverflowingData = br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position));
                }
            }
        }