public static Bitmap DecodeCatImage(ShandalarAsset asset)
        {
            //Console.WriteLine("Decompressing " + asset.filename);
            byte[] uncompressedData = Vlc.VlcDecompress(asset.data);

            int width          = (int)BitConverter.ToUInt32(asset.data, 0x1c);
            int height         = (int)BitConverter.ToUInt32(asset.data, 0x20);
            int smallTableSize = (int)BitConverter.ToUInt32(asset.data, 0x24);

            int newWidth;
            int newHeight;

            if ((int)BitConverter.ToUInt32(asset.data, 0) != 0)
            {
                bool halfSize = BitConverter.ToUInt32(asset.data, 0x28) == 1 ? true : false;
                if (halfSize)
                {
                    newWidth  = width / 2;
                    newHeight = height / 2;
                }
                else
                {
                    newWidth  = width;
                    newHeight = height;
                }
            }
            else
            {
                newWidth  = width;
                newHeight = height;
            }

            int ptr1 = 0;
            int ptr2 = ptr1 + width * width * 4 + 0x80;
            int ptr3 = ptr2 + newWidth * newWidth * 4 + 0x80;

            int[] tempArray = GeneralUtilityFunctions.ByteArrayToIntArray(uncompressedData, 0);

            Wavelet.WaveletDecode(ref tempArray, ptr1, width, smallTableSize);
            Wavelet.WaveletDecode(ref tempArray, ptr2 / 4, newWidth, smallTableSize);
            Wavelet.WaveletDecode(ref tempArray, ptr3 / 4, newWidth, smallTableSize);

            /// YCbCr -> RGB
            Bitmap outputImage = Wavelet.Decode_YCbCrToRGB(tempArray,
                                                           ptr1,
                                                           width,
                                                           height,
                                                           ptr2 / 4,
                                                           ptr3 / 4,
                                                           newWidth,
                                                           newHeight);

            // Return image
            return(outputImage);
        }
        public static byte[] VlcDecompress(byte[] srcBytes)          // 0x4928AF
        {
            int decompressedSize = (int)BitConverter.ToUInt32(srcBytes, 0x90) + 20000;

            byte[] result = new byte[decompressedSize];
            /// Block 1

            int ecx = (int)BitConverter.ToUInt32(srcBytes, 0x28) - 1;

            ecx = (ecx == 0) ? 1 : 2;

            int width  = (int)BitConverter.ToUInt32(srcBytes, 0x1c);
            int var_30 = width / ecx;
            int var_2C = var_30;

            /// Block 2

            ecx = BitConverter.ToUInt32(srcBytes, 0) == 0 ? 1 : 2;
            int var_18 = var_2C / ecx;
            int var_10 = var_18;

            byte[] dataPtr        = srcBytes.Skip(0x9c).ToArray();    // skip header
            int    smallTableSize = (int)BitConverter.ToUInt32(srcBytes, 0x24);

            int eax = var_18 * var_10;

            ecx = var_30 * var_2C;
            int var_C = ecx + 2 * eax;

            /// Step 1
            int dataOffset    = 0;
            int bigIndexCount = (int)BitConverter.ToUInt32(dataPtr, dataOffset);

            dataOffset += 4;

            int[] bigIndexTabPtr = GeneralUtilityFunctions.ByteArrayToIntArray(dataPtr, dataOffset);
            bigIndexTabPtr[0] = int.MinValue;

            dataOffset += bigIndexCount * 4;        // Skip large index table

            dataOffset += Vlc_GenTabs(dataPtr, dataOffset, bigIndexTabPtr, bigIndexCount);

            /// Loop

            int pieceNum = 0;        /// piece num

            while (pieceNum < BitConverter.ToUInt32(srcBytes, 0x28))
            {
                int size;

                /// Calculate pointers

                int tableSize     = smallTableSize * smallTableSize * 4;
                int var_24_offset = (var_C + 0x40) * pieceNum * 4;
                int var_38_offset = var_24_offset + var_30 * var_2C * 4 + 0x80;
                int var_34_offset = var_38_offset + var_18 * var_10 * 4 + 0x80;

                /// Small index table + data 1

                Array.Copy(dataPtr, dataOffset, result, var_24_offset, tableSize);
                var_24_offset += tableSize;
                dataOffset    += tableSize;

                size = (int)BitConverter.ToUInt32(srcBytes, pieceNum * 4 + 0x5c);
                Vlc_DecompressChunk(dataPtr, dataOffset, ref result, var_24_offset, size);
                dataOffset += size;

                /// Small index table + data 2

                Array.Copy(dataPtr, dataOffset, result, var_38_offset, tableSize);
                var_38_offset += tableSize;
                dataOffset    += tableSize;

                size = (int)BitConverter.ToUInt32(srcBytes, pieceNum * 4 + 0x6c);
                Vlc_DecompressChunk(dataPtr, dataOffset, ref result, var_38_offset, size);
                dataOffset += size;

                /// Small index table + data 3

                Array.Copy(dataPtr, dataOffset, result, var_34_offset, tableSize);
                var_34_offset += tableSize;
                dataOffset    += tableSize;

                size = (int)BitConverter.ToUInt32(srcBytes, pieceNum * 4 + 0x7c);

                Vlc_DecompressChunk(dataPtr, dataOffset, ref result, var_34_offset, size);
                dataOffset += size;

                pieceNum++;
            }
            return(result);
        }