Ejemplo n.º 1
0
        /// <summary>
        /// Decodes the specified level of the encoded texture to an array of RGBA8 pixels.
        /// </summary>
        /// <param name="level">The level of the texture to decode.</param>
        /// <param name="desiredStride">Desired stride (number of bytes per scanline) of the result.</param>
        /// <returns>An array with the RGBA8 data of the level (with no extra row padding).</returns>
        public byte[] DecodeLevelToRGBA8(int level, int desiredStride)
        {
            if (level < 0 || level >= LevelCount)
            {
                throw new ArgumentOutOfRangeException("level");
            }
            if (desiredStride < 0)
            {
                throw new ArgumentOutOfRangeException("desiredStride");
            }

            int levelWidth = WidthOfLevel(level), levelHeight = HeightOfLevel(level);

            if (desiredStride < levelWidth * 4)
            {
                throw new ArgumentOutOfRangeException("desiredStride", "Stride is too small to contain a row of data.");
            }

            // Decode texture as RGBA8 (GcTextureDecode format)
            byte[] decodedData = new byte[levelHeight * desiredStride];
            GcTextureFormatCodec.GetCodec(format).DecodeTexture(decodedData, 0,
                                                                levelWidth, levelHeight, desiredStride,
                                                                encodedLevelData[level], 0, null, 0);
            return(decodedData);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Calculates the size of a level of the texture.
        /// </summary>
        /// <param name="level">The level of the texture.</param>
        /// <param name="replicateCmprBug">true to replicate the F-Zero GX CMPR encoding bug.</param>
        /// <returns>The size of the encoded data in the specified level.</returns>
        private int CalculateSizeOfLevel(int level)
        {
            // Here we allow also to specify the "next" level for easier implementation
            // of the methods that encode the new texture
            if (level < 0 || level > LevelCount)
            {
                throw new ArgumentOutOfRangeException("level");
            }

            int levelWidth = width >> level, levelHeight = height >> level;

            return(GcTextureFormatCodec.GetCodec(format).CalcTextureSize(levelWidth, levelHeight));
        }
Ejemplo n.º 3
0
        private Texture2D ReadTexture(FileStream fs, EndianBinaryReader reader, int height, int width, LibGC.Texture.GcTextureFormat format)
        {
            GcTextureFormatCodec codec = GcTextureFormatCodec.GetCodec(format);
            int byteSize = codec.CalcTextureSize(width, height);
            //int stride = (width / block_width) * bpp / 8;
            int stride = width * 4;

            byte[]    imageData = reader.ReadBytes(byteSize);
            Texture2D tex       = new Texture2D(width, height, TextureFormat.RGBA32, false);

            byte[] destData = new byte[width * height * 4];
            codec.DecodeTexture(destData, 0, width, height, stride, imageData, 0, null, 0);
            tex.LoadRawTextureData(destData);
            tex.Apply();
            return(tex);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Create or replace the specified texture level from the specified image data.
        /// New texture levels must be created in order.
        /// </summary>
        /// <param name="level">The level of the texture to create or replace.</param>
        /// <param name="newImageDataStride">The stride (number of bytes per row) of the new image data.</param>
        /// <param name="newImageData">The new image data for the level.</param>
        public void DefineLevelData(int level, int newImageDataStride, byte[] newImageData)
        {
            if (level > LevelCount)             // We allow to either replace an existing level or to generate the next level
            {
                throw new ArgumentOutOfRangeException("level");
            }
            if (newImageDataStride < 0)
            {
                throw new ArgumentOutOfRangeException("newImageDataStride");
            }
            if (newImageData == null)
            {
                throw new ArgumentNullException("newImageData");
            }

            // Check that this texture level can be defined (size is not too small)
            // This checks that width and height can be divided evenly by 2^level
            if ((width & ((1 << level) - 1)) != 0 ||
                (height & ((1 << level) - 1)) != 0)
            {
                throw new ArgumentOutOfRangeException("level", "Level is too low for the image dimensions.");
            }

            int levelWidth  = width >> level;
            int levelHeight = height >> level;

            if (newImageDataStride < levelWidth * 4)
            {
                throw new ArgumentOutOfRangeException("newImageDataStride", "Stride is too small to contain a row of data.");
            }

            // Adding a new mipmap?
            if (level == LevelCount)
            {
                encodedLevelData.Add(new byte[CalculateSizeOfLevel(level)]);
            }

            // Encode
            GcTextureFormatCodec.GetCodec(format).EncodeTexture(
                newImageData, 0, levelWidth, levelHeight, newImageDataStride,
                encodedLevelData[level], 0, null, 0);
        }