Esempio n. 1
0
        public TextureFormat Open(System.IO.Stream formatData)
        {
            BinaryReader reader = new BinaryReader(formatData);

            try
            {
                char[] magic = reader.ReadChars(MAGIC.Length);
                if (new string(magic) != MAGIC)
                {
                    throw new TextureFormatException("Not a valid TX48 Texture!");
                }

                int bpp = reader.ReadInt32();
                if (bpp != 0 && bpp != 1)
                {
                    throw new TextureFormatException("Illegal Bit per pixel value!");
                }

                bpp = (bpp + 1) * 4;

                int width         = reader.ReadInt32();
                int height        = reader.ReadInt32();
                int paletteOffset = reader.ReadInt32();
                if (paletteOffset != 0x40)
                {
                    throw new TextureFormatException("TX48 Header is wrong!");
                }

                int paletteSize = reader.ReadInt32();
                int imageOffset = reader.ReadInt32();
                int imageSize   = reader.ReadInt32();
                reader.BaseStream.Position += 0x20;

                byte[] paletteData = reader.ReadBytes(paletteSize);
                byte[] imageData   = reader.ReadBytes(imageSize);

                PalettedTextureFormat.Builder builder = new PalettedTextureFormat.Builder();
                builder.SetPaletteCodec(ColorCodec.CODEC_32BIT_RGBA)
                .SetIndexCodec(IndexCodec.FromBitPerPixel(bpp));

                PalettedTextureFormat segment = builder.Build(imageData, paletteData, width, height);
                TX48Texture           texture = new TX48Texture();
                texture.TextureFormats.Add(segment);

                return(texture);
            }
            catch (Exception e)
            {
                if (e is TextureFormatException)
                {
                    throw;
                }
                throw new TextureFormatException(e.Message, e);
            }
        }
        private TextureFormat ConstructSegment(BinaryReader reader, ushort version)
        {
            ByteOrder order        = GetByteOrder();
            uint      totalSize    = reader.ReadUInt32(order);
            uint      paletteSize  = reader.ReadUInt32(order);
            uint      imageSize    = reader.ReadUInt32(order);
            uint      headerSize   = reader.ReadUInt16(order);
            int       colorsCount  = reader.ReadUInt16(order);
            byte      format       = reader.ReadByte();
            byte      mipmapsCount = reader.ReadByte();

            if (!IsSupportedFormat(format))
            {
                throw new TextureFormatException("Unsupported image format!");
            }

            byte clutFormat = reader.ReadByte();
            byte depth      = reader.ReadByte();

            int width  = reader.ReadUInt16(order);
            int height = reader.ReadUInt16(order);

            byte[] data = reader.ReadBytes(24);

            uint userDataSize = headerSize - 0x30;

            byte[] userdata = null;
            if (userDataSize > 0)
            {
                userdata = reader.ReadBytes((int)userDataSize);
            }

            int totalPixels = 0;

            for (int i = 0; i < mipmapsCount; i++)
            {
                totalPixels += ImageUtils.GetMipmapWidth(width, i) * ImageUtils.GetMipmapHeight(height, i);
            }

            int firstImageSize = mipmapsCount != 0? (int)((width * height * imageSize) / totalPixels) : 0;

            byte[] imgData = reader.ReadBytes(firstImageSize);
            //we don't need to load the mipmaps, since they can be generated as needed.
            //just skip the mipmaps
            reader.BaseStream.Position += (imageSize - firstImageSize);

            byte[] palData = reader.ReadBytes((int)paletteSize);

            TextureFormat segment = null;

            if (IsPaletted(clutFormat))
            {
                int colorSize         = GetPaletteColorSize(clutFormat);
                int numberOfPalettes  = palData.Length / (colorsCount * colorSize);
                int singlePaletteSize = palData.Length / numberOfPalettes;

                IList <byte[]> palettes = new List <byte[]>(numberOfPalettes);
                for (int i = 0; i < numberOfPalettes; i++)
                {
                    palettes.Add(palData.Skip(i * singlePaletteSize).Take(singlePaletteSize).ToArray());
                }

                PalettedTextureFormat.Builder builder = new PalettedTextureFormat.Builder();

                ColorCodec    paletteCodec;
                IndexCodec    indexCodec;
                ImageFilter   imgFilter;
                PaletteFilter palFilter;

                GetPalettedTools(version, clutFormat, depth, colorsCount, width, height, data, userdata,
                                 out paletteCodec, out indexCodec, out imgFilter, out palFilter);

                builder.SetPaletteCodec(paletteCodec)
                .SetMipmapsCount(mipmapsCount)
                .SetIndexCodec(indexCodec)
                .SetImageFilter(imgFilter)
                .SetPaletteFilter(palFilter);

                segment = builder.Build(imgData, palettes, width, height);
            }
            else
            {
                ColorCodec  imageCodec;
                ImageFilter imgFilter;
                GenericTextureFormat.Builder builder = new GenericTextureFormat.Builder();

                GetUnpalettedTools(version, clutFormat, depth, colorsCount, width, height, data, userdata,
                                   out imageCodec, out imgFilter);

                segment = builder.SetColorCodec(imageCodec)
                          .SetMipmapsCount(mipmapsCount)
                          .SetImageFilter(imgFilter)
                          .Build(imgData, width, height);
            }

            segment.FormatSpecificData.Put <byte>(CLUTFORMAT_KEY, clutFormat)
            .Put <byte>(FORMAT_KEY, format)
            .Put <byte>(DEPTH_KEY, depth)
            .Put <byte[]>(DATA_KEY, data)
            .Put <byte[]>(USERDATA_KEY, userdata);

            return(segment);
        }