Beispiel #1
0
        /// <summary>
        /// Decompresses an image.
        /// </summary>
        /// <param name="width">The width of the image to decompress.</param>
        /// <param name="height">The height of the image to decompress.</param>
        /// <param name="data">The compressed image data.</param>
        /// <param name="flags">The compression flags.</param>
        /// <returns>Returns the decompressed image as a byte array in the 32Bit RGBA-Format.</returns>
        internal static byte[] DecompressImage(int width, int height, byte[] data, DxtFlags flags)
        {
            var rgba = new byte[width * height * 4];

            // initialise the block input
            var sourceBlock_pos = 0;
            var bytesPerBlock   = (flags & DxtFlags.DXT1) != 0 ? 8 : 16;
            var targetRGBA      = new byte[4 * 16];

            // loop over blocks
            for (var y = 0; y < height; y += 4)
            {
                for (var x = 0; x < width; x += 4)
                {
                    // decompress the block
                    var targetRGBA_pos = 0;

                    if (data.Length == sourceBlock_pos)
                    {
                        continue;
                    }

                    Decompress(targetRGBA, data, sourceBlock_pos, flags);

                    // Write the decompressed pixels to the correct image locations
                    for (var py = 0; py < 4; py++)
                    {
                        for (var px = 0; px < 4; px++)
                        {
                            var sx = x + px;
                            var sy = y + py;
                            if (sx < width && sy < height)
                            {
                                var targetPixel = 4 * ((width * sy) + sx);

                                rgba[targetPixel + 0] = targetRGBA[targetRGBA_pos + 0];
                                rgba[targetPixel + 1] = targetRGBA[targetRGBA_pos + 1];
                                rgba[targetPixel + 2] = targetRGBA[targetRGBA_pos + 2];
                                rgba[targetPixel + 3] = targetRGBA[targetRGBA_pos + 3];

                                targetRGBA_pos += 4;
                            }
                            else
                            {
                                // Ignore that pixel
                                targetRGBA_pos += 4;
                            }
                        }
                    }

                    sourceBlock_pos += bytesPerBlock;
                }
            }

            return(rgba);
        }
Beispiel #2
0
        private static void Decompress(byte[] rgba, byte[] block, int blockIndex, DxtFlags flags)
        {
            // get the block locations
            var colorBlockIndex = blockIndex;

            if ((flags & (DxtFlags.DXT3 | DxtFlags.DXT5)) != 0)
            {
                colorBlockIndex += 8;
            }

            // decompress color
            DecompressColor(rgba, block, colorBlockIndex, (flags & DxtFlags.DXT1) != 0);

            // decompress alpha separately if necessary
            if ((flags & DxtFlags.DXT3) != 0)
            {
                DecompressAlphaDxt3(rgba, block, blockIndex);
            }
            else if ((flags & DxtFlags.DXT5) != 0)
            {
                DecompressAlphaDxt5(rgba, block, blockIndex);
            }
        }