Пример #1
0
        private ContentReader GetContentReaderFromXnb(string originalAssetName, ref Stream stream, BinaryReader xnbReader, char platform, Action <IDisposable> recordDisposableObject)
        {
            byte version    = xnbReader.ReadByte();
            byte flags      = xnbReader.ReadByte();
            bool compressed = (flags & 0x80) != 0;

            if (version != 5 && version != 4)
            {
                throw new ContentLoadException("Invalid XNB version");
            }
            // The next int32 is the length of the XNB file
            int           xnbLength = xnbReader.ReadInt32();
            ContentReader reader;

            if (compressed)
            {
                /* Decompress the XNB
                 * Thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
                 */
                int compressedSize   = xnbLength - 14;
                int decompressedSize = xnbReader.ReadInt32();

                // This will replace the XNB stream at the end
                MemoryStream decompressedStream = new MemoryStream(
                    new byte[decompressedSize],
                    0,
                    decompressedSize,
                    true,
                    true                     // This MUST be true! Readers may need GetBuffer()!
                    );

                /* Read in the whole XNB file at once, into a temp buffer.
                 * For slow disks, the extra malloc is more than worth the
                 * performance improvement from not constantly fread()ing!
                 */
                MemoryStream compressedStream = new MemoryStream(
                    new byte[compressedSize],
                    0,
                    compressedSize,
                    true,
                    true
                    );
                stream.Read(compressedStream.GetBuffer(), 0, compressedSize);

                // Default window size for XNB encoded files is 64Kb (need 16 bits to represent it)
                LzxDecoder dec          = new LzxDecoder(16);
                int        decodedBytes = 0;
                long       pos          = 0;

                while (pos < compressedSize)
                {
                    /* The compressed stream is separated into blocks that will
                     * decompress into 32kB or some other size if specified.
                     * Normal, 32kB output blocks will have a short indicating
                     * the size of the block before the block starts. Blocks
                     * that have a defined output will be preceded by a byte of
                     * value 0xFF (255), then a short indicating the output size
                     * and another for the block size. All shorts for these
                     * cases are encoded in big endian order.
                     */
                    int hi         = compressedStream.ReadByte();
                    int lo         = compressedStream.ReadByte();
                    int block_size = (hi << 8) | lo;
                    int frame_size = 0x8000;                     // Frame size is 32kB by default
                    // Does this block define a frame size?
                    if (hi == 0xFF)
                    {
                        hi         = lo;
                        lo         = (byte)compressedStream.ReadByte();
                        frame_size = (hi << 8) | lo;
                        hi         = (byte)compressedStream.ReadByte();
                        lo         = (byte)compressedStream.ReadByte();
                        block_size = (hi << 8) | lo;
                        pos       += 5;
                    }
                    else
                    {
                        pos += 2;
                    }
                    // Either says there is nothing to decode
                    if (block_size == 0 || frame_size == 0)
                    {
                        break;
                    }
                    dec.Decompress(compressedStream, block_size, decompressedStream, frame_size);
                    pos          += block_size;
                    decodedBytes += frame_size;

                    /* Reset the position of the input just in case the bit
                     * buffer read in some unused bytes.
                     */
                    compressedStream.Seek(pos, SeekOrigin.Begin);
                }
                if (decompressedStream.Position != decompressedSize)
                {
                    throw new ContentLoadException(
                              "Decompression of " + originalAssetName + " failed. "
                              );
                }
                decompressedStream.Seek(0, SeekOrigin.Begin);
                reader = new ContentReader(
                    this,
                    decompressedStream,
                    originalAssetName,
                    version,
                    platform,
                    recordDisposableObject
                    );
            }
            else
            {
                reader = new ContentReader(
                    this,
                    stream,
                    originalAssetName,
                    version,
                    platform,
                    recordDisposableObject
                    );
            }
            return(reader);
        }
Пример #2
0
        private static Stream PrepareStream(Stream input, string assetName)
        {
            Stream stream;

            try
            {
                bool         flag;                                                                               //Compressionflag
                BinaryReader reader = new BinaryReader(input);
                if (((reader.ReadByte() != 0x58) || (reader.ReadByte() != 0x4e)) || (reader.ReadByte() != 0x42)) //First three bytes have to be "XNB"
                {
                    throw new ContentLoadException("Bad XNB Magic");
                }
                if (reader.ReadByte() != 0x77) //Platform have to be "w" -> stands for windows
                {
                    throw new ContentLoadException("Bad XNB Platform");
                }
                switch (reader.ReadUInt16()) //Version
                {
                case 3:
                case 4:
                    flag = false;     //Not compressed Stream
                    break;

                case 0x8003:
                case 0x8004:
                    flag = true;     //Compressed Stream
                    break;

                default:
                    throw new ContentLoadException("Bad XNB Version");
                }
                int num = reader.ReadInt32();                                        //Number of bytes
                if (input.CanSeek && ((num - 10) > (input.Length - input.Position))) //Check if we can read the expected number of bytes
                {
                    throw new ContentLoadException("Bad XNB Size");
                }

                // is the stream compressed?
                if (flag)
                {
                    // ... let's decompress it!
                    // get the decompressed size (num is our compressed size)
                    int decompressedSize = reader.ReadInt32();
                    // create a memory stream of that size
                    MemoryStream output = new MemoryStream(decompressedSize);

                    // save our initial position
                    long pos = input.Position;
                    // default window size for XNB encoded files is 64Kb (need 16 bits to represent it)
                    LzxDecoder decoder = new LzxDecoder(16);
                    // start our decode process
                    while (pos < num)
                    {
                        // the compressed stream is seperated into blocks that will decompress
                        // into 32Kb or some other size if specified.
                        // normal, 32Kb output blocks will have a short indicating the size
                        // of the block before the block starts
                        // blocks that have a defined output will be preceded by a byte of value
                        // 0xFF (255), then a short indicating the output size and another
                        // for the block size
                        // all shorts for these cases are encoded in big endian order
                        int hi, lo, block_size, frame_size;
                        // let's get the first byte
                        hi = reader.ReadByte();
                        // does this block define a frame size?
                        if (hi == 0xFF)
                        {
                            // get our bytes
                            hi = reader.ReadByte();
                            lo = reader.ReadByte();
                            // make a beautiful short baby together
                            frame_size = (hi << 8) | lo;
                            // let's read the block size
                            hi         = reader.ReadByte();
                            lo         = reader.ReadByte();
                            block_size = (hi << 8) | lo;
                            // add the read in bytes to the position
                            pos += 5;
                        }
                        else
                        {
                            // just block size, so let's read the rest
                            lo         = reader.ReadByte();
                            block_size = (hi << 8) | lo;
                            // frame size is 32Kb by default
                            frame_size = 32768;
                            // add the read in bytes to the position
                            pos += 2;
                        }

                        // either says there is nothing to decode
                        if (block_size == 0 || frame_size == 0)
                        {
                            break;
                        }

                        // let's decompress the sucker
                        decoder.Decompress(input, block_size, output, frame_size);

                        // let's increment the input position by the block size
                        pos += block_size;
                        // reset the position of the input just incase the bit buffer
                        // read in some unused bytes
                        input.Seek(pos, SeekOrigin.Begin);
                    }

                    // finished decoding everything, let's set the decompressed buffer
                    // to the beginning and return that
                    output.Seek(0, SeekOrigin.Begin);
                    stream = output;
                }
                else // if not, return the input stream untouched
                {
                    stream = input;
                }
            }
            catch (IOException exception)
            {
                throw new ContentLoadException("Bad XNB", exception);
            }
            return(stream);
        }
Пример #3
0
        private ContentReader GetContentReaderFromXnb(string originalAssetName, ref Stream stream, BinaryReader xnbReader, Action <IDisposable> recordDisposableObject)
        {
            // The first 4 bytes should be the "XNB" header. i use that to detect an invalid file
            byte x        = xnbReader.ReadByte();
            byte n        = xnbReader.ReadByte();
            byte b        = xnbReader.ReadByte();
            byte platform = xnbReader.ReadByte();

            if (x != 'X' || n != 'N' || b != 'B' ||
                !(targetPlatformIdentifiers.Contains((char)platform)))
            {
                throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?");
            }

            byte version = xnbReader.ReadByte();
            byte flags   = xnbReader.ReadByte();

            bool compressedLzx = (flags & ContentCompressedLzx) != 0;
            bool compressedLz4 = (flags & ContentCompressedLz4) != 0;

            if (version != 5 && version != 4)
            {
                throw new ContentLoadException("Invalid XNB version");
            }

            // The next int32 is the length of the XNB file
            int xnbLength = xnbReader.ReadInt32();

            ContentReader reader;

            if (compressedLzx || compressedLz4)
            {
                // Decompress the xnb
                int          decompressedSize   = xnbReader.ReadInt32();
                MemoryStream decompressedStream = null;

                if (compressedLzx)
                {
                    //thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
                    // default window size for XNB encoded files is 64Kb (need 16 bits to represent it)
                    LzxDecoder dec = new LzxDecoder(16);
                    decompressedStream = new MemoryStream(decompressedSize);
                    int  compressedSize = xnbLength - 14;
                    long startPos       = stream.Position;
                    long pos            = startPos;

                    while (pos - startPos < compressedSize)
                    {
                        // the compressed stream is seperated into blocks that will decompress
                        // into 32Kb or some other size if specified.
                        // normal, 32Kb output blocks will have a short indicating the size
                        // of the block before the block starts
                        // blocks that have a defined output will be preceded by a byte of value
                        // 0xFF (255), then a short indicating the output size and another
                        // for the block size
                        // all shorts for these cases are encoded in big endian order
                        int hi         = stream.ReadByte();
                        int lo         = stream.ReadByte();
                        int block_size = (hi << 8) | lo;
                        int frame_size = 0x8000; // frame size is 32Kb by default
                        // does this block define a frame size?
                        if (hi == 0xFF)
                        {
                            hi         = lo;
                            lo         = (byte)stream.ReadByte();
                            frame_size = (hi << 8) | lo;
                            hi         = (byte)stream.ReadByte();
                            lo         = (byte)stream.ReadByte();
                            block_size = (hi << 8) | lo;
                            pos       += 5;
                        }
                        else
                        {
                            pos += 2;
                        }

                        // either says there is nothing to decode
                        if (block_size == 0 || frame_size == 0)
                        {
                            break;
                        }

                        dec.Decompress(stream, block_size, decompressedStream, frame_size);
                        pos += block_size;

                        // reset the position of the input just incase the bit buffer
                        // read in some unused bytes
                        stream.Seek(pos, SeekOrigin.Begin);
                    }

                    if (decompressedStream.Position != decompressedSize)
                    {
                        throw new ContentLoadException("Decompression of " + originalAssetName + " failed. ");
                    }

                    decompressedStream.Seek(0, SeekOrigin.Begin);
                }
                else if (compressedLz4)
                {
                    // Decompress to a byte[] because Windows 8 doesn't support MemoryStream.GetBuffer()
                    var buffer = new byte[decompressedSize];
                    using (var decoderStream = new Lz4DecoderStream(stream))
                    {
                        if (decoderStream.Read(buffer, 0, buffer.Length) != decompressedSize)
                        {
                            throw new ContentLoadException("Decompression of " + originalAssetName + " failed. ");
                        }
                    }
                    // Creating the MemoryStream with a byte[] shares the buffer so it doesn't allocate any more memory
                    decompressedStream = new MemoryStream(buffer);
                }

                reader = new ContentReader(this, decompressedStream, this.graphicsDeviceService.GraphicsDevice,
                                           originalAssetName, version, recordDisposableObject);
            }
            else
            {
                reader = new ContentReader(this, stream, this.graphicsDeviceService.GraphicsDevice,
                                           originalAssetName, version, recordDisposableObject);
            }
            return(reader);
        }
Пример #4
0
        private ContentReader GetContentReaderFromXnb(string originalAssetName, ref Stream stream, BinaryReader xnbReader, Action <IDisposable> recordDisposableObject)
        {
            // The first 4 bytes should be the "XNB" header.
            byte x        = xnbReader.ReadByte();
            byte n        = xnbReader.ReadByte();
            byte b        = xnbReader.ReadByte();
            byte platform = xnbReader.ReadByte();

            if (x != 'X' || n != 'N' || b != 'B' ||
                !(targetPlatformIdentifiers.Contains((char)platform)))
            {
                throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?");
            }
            byte version    = xnbReader.ReadByte();
            byte flags      = xnbReader.ReadByte();
            bool compressed = (flags & 0x80) != 0;

            if (version != 5 && version != 4)
            {
                throw new ContentLoadException("Invalid XNB version");
            }
            // The next int32 is the length of the XNB file
            int           xnbLength = xnbReader.ReadInt32();
            ContentReader reader;

            if (compressed)
            {
                /* Decompress the XNB
                 * Thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
                 */
                int          compressedSize     = xnbLength - 14;
                int          decompressedSize   = xnbReader.ReadInt32();
                MemoryStream decompressedStream = new MemoryStream(decompressedSize);
                // Default window size for XNB encoded files is 64Kb (need 16 bits to represent it)
                LzxDecoder dec          = new LzxDecoder(16);
                int        decodedBytes = 0;
                long       startPos     = stream.Position;
                long       pos          = startPos;

                while (pos - startPos < compressedSize)
                {
                    /* The compressed stream is separated into blocks that will
                     * decompress into 32kB or some other size if specified.
                     * Normal, 32kB output blocks will have a short indicating
                     * the size of the block before the block starts. Blocks
                     * that have a defined output will be preceded by a byte of
                     * value 0xFF (255), then a short indicating the output size
                     * and another for the block size. All shorts for these
                     * cases are encoded in big endian order.
                     */
                    int hi         = stream.ReadByte();
                    int lo         = stream.ReadByte();
                    int block_size = (hi << 8) | lo;
                    int frame_size = 0x8000;                     // Frame size is 32kB by default
                    // Does this block define a frame size?
                    if (hi == 0xFF)
                    {
                        hi         = lo;
                        lo         = (byte)stream.ReadByte();
                        frame_size = (hi << 8) | lo;
                        hi         = (byte)stream.ReadByte();
                        lo         = (byte)stream.ReadByte();
                        block_size = (hi << 8) | lo;
                        pos       += 5;
                    }
                    else
                    {
                        pos += 2;
                    }
                    // Either says there is nothing to decode
                    if (block_size == 0 || frame_size == 0)
                    {
                        break;
                    }
                    dec.Decompress(stream, block_size, decompressedStream, frame_size);
                    pos          += block_size;
                    decodedBytes += frame_size;

                    /* Reset the position of the input just in case the bit
                     * buffer read in some unused bytes.
                     */
                    stream.Seek(pos, SeekOrigin.Begin);
                }
                if (decompressedStream.Position != decompressedSize)
                {
                    throw new ContentLoadException(
                              "Decompression of " + originalAssetName + " failed. "
                              );
                }
                decompressedStream.Seek(0, SeekOrigin.Begin);
                reader = new ContentReader(
                    this,
                    decompressedStream,
                    this.graphicsDeviceService.GraphicsDevice,
                    originalAssetName,
                    version,
                    recordDisposableObject
                    );
            }
            else
            {
                reader = new ContentReader(
                    this,
                    stream,
                    this.graphicsDeviceService.GraphicsDevice,
                    originalAssetName,
                    version,
                    recordDisposableObject
                    );
            }
            return(reader);
        }
Пример #5
0
        private ContentReader GetContentReaderFromXnb(string originalAssetName, ref Stream stream, BinaryReader xnbReader, Action <IDisposable> recordDisposableObject)
        {
            // The first 4 bytes should be the "XNB" header. i use that to detect an invalid file
            byte x        = xnbReader.ReadByte();
            byte n        = xnbReader.ReadByte();
            byte b        = xnbReader.ReadByte();
            byte platform = xnbReader.ReadByte();

            if (x != 'X' || n != 'N' || b != 'B' ||
                !(targetPlatformIdentifiers.Contains((char)platform)))
            {
                throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?");
            }

            byte version = xnbReader.ReadByte();
            byte flags   = xnbReader.ReadByte();

            bool compressed = (flags & 0x80) != 0;

            if (version != 5 && version != 4)
            {
                throw new ContentLoadException("Invalid XNB version");
            }

            // The next int32 is the length of the XNB file
            int xnbLength = xnbReader.ReadInt32();

            ContentReader reader;

            if (compressed)
            {
                //decompress the xnb
                //thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
                int compressedSize   = xnbLength - 14;
                int decompressedSize = xnbReader.ReadInt32();

                MemoryStream decompressedStream = new MemoryStream(decompressedSize);

                // default window size for XNB encoded files is 64Kb (need 16 bits to represent it)
                LzxDecoder dec          = new LzxDecoder(16);
                int        decodedBytes = 0;
                long       startPos     = stream.Position;
                long       pos          = startPos;

#if ANDROID
                // Android native stream does not support the Position property. LzxDecoder.Decompress also uses
                // Seek.  So we read the entirity of the stream into a memory stream and replace stream with the
                // memory stream.
                MemoryStream memStream = new MemoryStream();
                stream.CopyTo(memStream);
                memStream.Seek(0, SeekOrigin.Begin);
                stream.Dispose();
                stream = memStream;
                // Position is at the start of the MemoryStream as Stream.CopyTo copies from current position
                pos = 0;
#endif

                while (pos - startPos < compressedSize)
                {
                    // the compressed stream is seperated into blocks that will decompress
                    // into 32Kb or some other size if specified.
                    // normal, 32Kb output blocks will have a short indicating the size
                    // of the block before the block starts
                    // blocks that have a defined output will be preceded by a byte of value
                    // 0xFF (255), then a short indicating the output size and another
                    // for the block size
                    // all shorts for these cases are encoded in big endian order
                    int hi         = stream.ReadByte();
                    int lo         = stream.ReadByte();
                    int block_size = (hi << 8) | lo;
                    int frame_size = 0x8000; // frame size is 32Kb by default
                    // does this block define a frame size?
                    if (hi == 0xFF)
                    {
                        hi         = lo;
                        lo         = (byte)stream.ReadByte();
                        frame_size = (hi << 8) | lo;
                        hi         = (byte)stream.ReadByte();
                        lo         = (byte)stream.ReadByte();
                        block_size = (hi << 8) | lo;
                        pos       += 5;
                    }
                    else
                    {
                        pos += 2;
                    }

                    // either says there is nothing to decode
                    if (block_size == 0 || frame_size == 0)
                    {
                        break;
                    }

                    dec.Decompress(stream, block_size, decompressedStream, frame_size);
                    pos          += block_size;
                    decodedBytes += frame_size;

                    // reset the position of the input just incase the bit buffer
                    // read in some unused bytes
                    stream.Seek(pos, SeekOrigin.Begin);
                }

                if (decompressedStream.Position != decompressedSize)
                {
                    throw new ContentLoadException("Decompression of " + originalAssetName + " failed. ");
                }

                decompressedStream.Seek(0, SeekOrigin.Begin);
                reader = new ContentReader(this, decompressedStream, this.graphicsDeviceService.GraphicsDevice,
                                           originalAssetName, version, recordDisposableObject);
            }
            else
            {
                reader = new ContentReader(this, stream, this.graphicsDeviceService.GraphicsDevice,
                                           originalAssetName, version, recordDisposableObject);
            }
            return(reader);
        }
Пример #6
0
 private uint ReadHuffSym(ushort[] table, byte[] lengths, uint nsyms, uint nbits, LzxDecoder.BitBuffer bitbuf)
 {
   bitbuf.EnsureBits((byte) 16);
   uint num1;
   if ((num1 = (uint) table[(IntPtr) bitbuf.PeekBits((byte) nbits)]) >= nsyms)
   {
     uint num2 = (uint) (1 << 32 - (int) nbits);
     uint num3;
     do
     {
       num2 >>= 1;
       num3 = num1 << 1 | (((int) bitbuf.GetBuffer() & (int) num2) != 0 ? 1U : 0U);
       if ((int) num2 == 0)
         return 0U;
     }
     while ((num1 = (uint) table[(IntPtr) num3]) >= nsyms);
   }
   uint num4 = (uint) lengths[(IntPtr) num1];
   bitbuf.RemoveBits((byte) num4);
   return num1;
 }
Пример #7
0
        private ContentReader GetContentReaderFromXnb(string originalAssetName, ref Stream stream, BinaryReader xnbReader, Action <IDisposable> recordDisposableObject)
        {
            byte num1 = xnbReader.ReadByte();
            byte num2 = xnbReader.ReadByte();
            byte num3 = xnbReader.ReadByte();
            byte num4 = xnbReader.ReadByte();

            if ((int)num1 != 88 || (int)num2 != 78 || (int)num3 != 66 || (int)num4 != 119 && (int)num4 != 120 && (int)num4 != 109)
            {
                throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?");
            }
            byte num5 = xnbReader.ReadByte();
            bool flag = ((int)xnbReader.ReadByte() & 128) != 0;

            if ((int)num5 != 5 && (int)num5 != 4)
            {
                throw new ContentLoadException("Invalid XNB version");
            }
            int           num6 = xnbReader.ReadInt32();
            ContentReader contentReader;

            if (flag)
            {
                int          num7         = num6 - 14;
                int          capacity     = xnbReader.ReadInt32();
                MemoryStream memoryStream = new MemoryStream(capacity);
                LzxDecoder   lzxDecoder   = new LzxDecoder(16);
                int          num8         = 0;
                long         position     = stream.Position;
                long         offset       = position;
                while (offset - position < (long)num7)
                {
                    int  num9   = stream.ReadByte();
                    int  num10  = stream.ReadByte();
                    int  inLen  = num9 << 8 | num10;
                    int  outLen = 32768;
                    long num11;
                    if (num9 == (int)byte.MaxValue)
                    {
                        outLen = num10 << 8 | (int)(byte)stream.ReadByte();
                        inLen  = (int)(byte)stream.ReadByte() << 8 | (int)(byte)stream.ReadByte();
                        num11  = offset + 5L;
                    }
                    else
                    {
                        num11 = offset + 2L;
                    }
                    if (inLen != 0 && outLen != 0)
                    {
                        lzxDecoder.Decompress(stream, inLen, (Stream)memoryStream, outLen);
                        offset = num11 + (long)inLen;
                        num8  += outLen;
                        stream.Seek(offset, SeekOrigin.Begin);
                    }
                    else
                    {
                        break;
                    }
                }
                if (memoryStream.Position != (long)capacity)
                {
                    throw new ContentLoadException("Decompression of " + originalAssetName + " failed. ");
                }
                memoryStream.Seek(0L, SeekOrigin.Begin);
                contentReader = new ContentReader(this, (Stream)memoryStream, this.graphicsDeviceService.GraphicsDevice, originalAssetName, (int)num5, recordDisposableObject);
            }
            else
            {
                contentReader = new ContentReader(this, stream, this.graphicsDeviceService.GraphicsDevice, originalAssetName, (int)num5, recordDisposableObject);
            }
            return(contentReader);
        }
Пример #8
0
 private void ReadLengths(byte[] lens, uint first, uint last, LzxDecoder.BitBuffer bitbuf)
 {
   for (uint index = 0U; index < 20U; ++index)
   {
     uint num = bitbuf.ReadBits((byte) 4);
     this.m_state.PRETREE_len[(IntPtr) index] = (byte) num;
   }
   this.MakeDecodeTable(20U, 6U, this.m_state.PRETREE_len, this.m_state.PRETREE_table);
   uint num1 = first;
   while (num1 < last)
   {
     int num2 = (int) this.ReadHuffSym(this.m_state.PRETREE_table, this.m_state.PRETREE_len, 20U, 6U, bitbuf);
     switch (num2)
     {
       case 17:
         uint num3 = bitbuf.ReadBits((byte) 4) + 4U;
         while ((int) num3-- != 0)
           lens[(IntPtr) num1++] = (byte) 0;
         continue;
       case 18:
         uint num4 = bitbuf.ReadBits((byte) 5) + 20U;
         while ((int) num4-- != 0)
           lens[(IntPtr) num1++] = (byte) 0;
         continue;
       case 19:
         uint num5 = bitbuf.ReadBits((byte) 1) + 4U;
         int num6 = (int) this.ReadHuffSym(this.m_state.PRETREE_table, this.m_state.PRETREE_len, 20U, 6U, bitbuf);
         int num7 = (int) lens[(IntPtr) num1] - num6;
         if (num7 < 0)
           num7 += 17;
         while ((int) num5-- != 0)
           lens[(IntPtr) num1++] = (byte) num7;
         continue;
       default:
         int num8 = (int) lens[(IntPtr) num1] - num2;
         if (num8 < 0)
           num8 += 17;
         lens[(IntPtr) num1++] = (byte) num8;
         continue;
     }
   }
 }
Пример #9
0
        protected T ReadAsset <T>(string assetName, Action <IDisposable> recordDisposableObject)
        {
            if (string.IsNullOrEmpty(assetName))
            {
                throw new ArgumentNullException();
            }
            if (disposed)
            {
                throw new ObjectDisposedException("ContentManager");
            }

            string originalAssetName = assetName;
            object result            = null;

            if (this.graphicsDeviceService == null)
            {
                this.graphicsDeviceService = serviceProvider.GetService(typeof(IGraphicsDeviceService)) as IGraphicsDeviceService;
                if (this.graphicsDeviceService == null)
                {
                    throw new InvalidOperationException("No Graphics Device Service");
                }
            }

            // Replace Windows path separators with local path separators
            assetName = Path.Combine(_rootDirectory, assetName.Replace('\\', Path.DirectorySeparatorChar));

            // Get the real file name
            if ((typeof(T) == typeof(Texture2D)))
            {
                assetName = Texture2DReader.Normalize(assetName);
            }
            else if ((typeof(T) == typeof(SpriteFont)))
            {
                assetName = SpriteFontReader.Normalize(assetName);
            }
            else if ((typeof(T) == typeof(Effect)))
            {
                assetName = Effect.Normalize(assetName);
            }
            else if ((typeof(T) == typeof(Song)))
            {
                assetName = SongReader.Normalize(assetName);
            }
            else if ((typeof(T) == typeof(SoundEffect)))
            {
                assetName = SoundEffectReader.Normalize(assetName);
            }
            else if ((typeof(T) == typeof(Video)))
            {
                assetName = Video.Normalize(assetName);
            }
            else
            {
                throw new NotSupportedException("Format not supported");
            }

            if (string.IsNullOrEmpty(assetName))
            {
                throw new ContentLoadException("Could not load " + originalAssetName + " asset!");
            }

            if (!Path.HasExtension(assetName))
            {
                assetName = string.Format("{0}.xnb", assetName);
            }

            if (Path.GetExtension(assetName).ToUpper() == ".XNB")
            {
                // Load a XNB file
                //Loads from Assets directory + /assetName
                Stream       stream    = OpenStream(assetName);
                BinaryReader xnbReader = new BinaryReader(stream);

                // The first 4 bytes should be the "XNB" header. i use that to detect an invalid file
                byte[] headerBuffer = new byte[3];
                xnbReader.Read(headerBuffer, 0, 3);

                string headerString = Encoding.UTF8.GetString(headerBuffer, 0, 3);

                byte platform = xnbReader.ReadByte();

                if (string.Compare(headerString, "XNB") != 0 ||
                    !(platform == 'w' || platform == 'x' || platform == 'm'))
                {
                    throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?");
                }

                ushort version         = xnbReader.ReadUInt16();
                int    graphicsProfile = version & 0x7f00;
                version &= 0x80ff;

                bool compressed = false;
                if (version == 0x8005 || version == 0x8004)
                {
                    compressed = true;
                }
                else if (version != 5 && version != 4)
                {
                    throw new ContentLoadException("Invalid XNB version");
                }

                // The next int32 is the length of the XNB file
                int xnbLength = xnbReader.ReadInt32();

                ContentReader reader;
                if (compressed)
                {
                    //decompress the xnb
                    //thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
                    int compressedSize   = xnbLength - 14;
                    int decompressedSize = xnbReader.ReadInt32();
                    int newFileSize      = decompressedSize + 10;

                    MemoryStream decompressedStream = new MemoryStream(decompressedSize);

                    LzxDecoder dec          = new LzxDecoder(16);
                    int        decodedBytes = 0;
                    int        pos          = 0;

                    while (pos < compressedSize)
                    {
                        // let's seek to the correct position
                        stream.Seek(pos + 14, SeekOrigin.Begin);
                        int hi         = stream.ReadByte();
                        int lo         = stream.ReadByte();
                        int block_size = (hi << 8) | lo;
                        int frame_size = 0x8000;
                        if (hi == 0xFF)
                        {
                            hi         = lo;
                            lo         = (byte)stream.ReadByte();
                            frame_size = (hi << 8) | lo;
                            hi         = (byte)stream.ReadByte();
                            lo         = (byte)stream.ReadByte();
                            block_size = (hi << 8) | lo;
                            pos       += 5;
                        }
                        else
                        {
                            pos += 2;
                        }

                        if (block_size == 0 || frame_size == 0)
                        {
                            break;
                        }

                        int lzxRet = dec.Decompress(stream, block_size, decompressedStream, frame_size);
                        pos          += block_size;
                        decodedBytes += frame_size;
                    }

                    if (decompressedStream.Position != decompressedSize)
                    {
                        throw new ContentLoadException("Decompression of " + originalAssetName + "failed. " +
                                                       " Try decompressing with nativeDecompressXnb first.");
                    }

                    decompressedStream.Seek(0, SeekOrigin.Begin);
                    reader = new ContentReader(this, decompressedStream, this.graphicsDeviceService.GraphicsDevice);
                }
                else
                {
                    reader = new ContentReader(this, stream, this.graphicsDeviceService.GraphicsDevice);
                }

                ContentTypeReaderManager typeManager = new ContentTypeReaderManager(reader);
                reader.TypeReaders = typeManager.LoadAssetReaders(reader);
                foreach (ContentTypeReader r in reader.TypeReaders)
                {
                    r.Initialize(typeManager);
                }
                // we need to read a byte here for things to work out, not sure why
                reader.ReadByte();

                // Get the 1-based index of the typereader we should use to start decoding with
                int index = reader.ReadByte();
                ContentTypeReader contentReader = reader.TypeReaders[index - 1];
                result = reader.ReadObject <T>(contentReader);

                reader.Close();
                stream.Close();
            }
            else
            {
                if ((typeof(T) == typeof(Texture2D)))
                {
                    //Basically the same as Texture2D.FromFile but loading from the assets instead of a filePath
                    Stream  assetStream = OpenStream(assetName);
                    Bitmap  image       = BitmapFactory.DecodeStream(assetStream);
                    ESImage theTexture  = new ESImage(image, graphicsDeviceService.GraphicsDevice.PreferedFilter);
                    result = new Texture2D(theTexture)
                    {
                        Name = Path.GetFileNameWithoutExtension(assetName)
                    };
                }
                if ((typeof(T) == typeof(SpriteFont)))
                {
                    //result = new SpriteFont(Texture2D.FromFile(graphicsDeviceService.GraphicsDevice,assetName), null, null, null, 0, 0.0f, null, null);
                    throw new NotImplementedException();
                }

                if ((typeof(T) == typeof(Song)))
                {
                    result = new Song(assetName);
                }
                if ((typeof(T) == typeof(SoundEffect)))
                {
                    result = new SoundEffect(assetName);
                }
                if ((typeof(T) == typeof(Video)))
                {
                    result = new Video(assetName);
                }
            }

            /*else
             * {
             *      // Load a XNB file
             * //Loads from Assets directory + /assetName
             *  Stream assetStream = OpenStream(assetName);
             *
             * ContentReader reader = new ContentReader(this, assetStream, this.graphicsDeviceService.GraphicsDevice);
             *      ContentTypeReaderManager typeManager = new ContentTypeReaderManager(reader);
             *      reader.TypeReaders = typeManager.LoadAssetReaders(reader);
             * foreach (ContentTypeReader r in reader.TypeReaders)
             * {
             * r.Initialize(typeManager);
             * }
             * // we need to read a byte here for things to work out, not sure why
             * reader.ReadByte();
             *
             *      // Get the 1-based index of the typereader we should use to start decoding with
             * int index = reader.ReadByte();
             *      ContentTypeReader contentReader = reader.TypeReaders[index - 1];
             * result = reader.ReadObject<T>(contentReader);
             *
             *      reader.Close();
             *      assetStream.Close();
             * }*/

            if (result == null)
            {
                throw new ContentLoadException("Could not load " + originalAssetName + " asset!");
            }

            // Store references to the asset for later use
            T asset = (T)result;

            if (asset is IDisposable && recordDisposableObject != null)
            {
                recordDisposableObject(asset as IDisposable);
            }
            else
            {
                disposableAssets.Add(asset as IDisposable);
            }
            loadedAssets.Add(originalAssetName, asset);

            return((T)result);
        }
Пример #10
0
        public T Load <T>(string assetName)
        {
            string originalAssetName = assetName;
            object result            = null;

            if (this.graphicsDeviceService == null)
            {
                this.graphicsDeviceService = serviceProvider.GetService(typeof(IGraphicsDeviceService)) as IGraphicsDeviceService;
                if (this.graphicsDeviceService == null)
                {
                    throw new InvalidOperationException("No Graphics Device Service");
                }
            }

            if (string.IsNullOrEmpty(assetName))
            {
                throw new ArgumentException("assetname");
            }

            if (!string.IsNullOrEmpty(_rootDirectory))
            {
                assetName = _rootDirectory + Path.DirectorySeparatorChar + assetName;
            }

            // Check for windows-style directory separator character
            assetName = assetName.Replace('\\', Path.DirectorySeparatorChar);

            // Get the real file name
            if ((typeof(T) == typeof(Texture2D)))
            {
                assetName = Texture2DReader.Normalize(assetName);
            }
            if ((typeof(T) == typeof(SpriteFont)))
            {
                assetName = SpriteFontReader.Normalize(assetName);
            }
            if ((typeof(T) == typeof(Song)))
            {
                assetName = SongReader.Normalize(assetName);
            }
            if ((typeof(T) == typeof(SoundEffect)))
            {
                assetName = SoundEffectReader.Normalize(assetName);
            }
            if ((typeof(T) == typeof(Video)))
            {
                assetName = Video.Normalize(assetName);
            }
            if ((typeof(T) == typeof(Effect)))
            {
                assetName = Effect.Normalize(assetName);
            }

            if (string.IsNullOrEmpty(assetName))
            {
                throw new ContentLoadException("Could not load " + originalAssetName + " asset!");
            }

            if (!Path.HasExtension(assetName))
            {
                assetName = string.Format("{0}.xnb", assetName);
            }

            if (Path.GetExtension(assetName).ToUpper() == ".XNB")
            {
                // Load a XNB file
                FileStream   stream    = new FileStream(assetName, FileMode.Open, FileAccess.Read, FileShare.Read);
                BinaryReader xnbReader = new BinaryReader(stream);

                // The first 4 bytes should be the "XNB" header. i use that to detect an invalid file
                byte[] headerBuffer = new byte[3];
                xnbReader.Read(headerBuffer, 0, 3);

                string headerString = Encoding.UTF8.GetString(headerBuffer, 0, 3);

                byte platform = xnbReader.ReadByte();

                if (string.Compare(headerString, "XNB") != 0 ||
                    !(platform == 'w' || platform == 'x' || platform == 'm'))
                {
                    throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?");
                }

                ushort version         = xnbReader.ReadUInt16();
                int    graphicsProfile = version & 0x7f00;
                version &= 0x80ff;

                bool compressed = false;
                if (version == 0x8005 || version == 0x8004)
                {
                    compressed = true;
                }
                else if (version != 5 && version != 4)
                {
                    throw new ContentLoadException("Invalid XNB version");
                }

                // The next int32 is the length of the XNB file
                int xnbLength = xnbReader.ReadInt32();

                ContentReader reader;
                if (compressed)
                {
                    //decompress the xnb
                    //thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
                    int compressedSize   = xnbLength - 14;
                    int decompressedSize = xnbReader.ReadInt32();
                    int newFileSize      = decompressedSize + 10;

                    MemoryStream decompressedStream = new MemoryStream(decompressedSize);

                    LzxDecoder dec          = new LzxDecoder(16);
                    int        decodedBytes = 0;
                    int        pos          = 0;

                    while (pos < compressedSize)
                    {
                        // let's seek to the correct position
                        stream.Seek(pos + 14, SeekOrigin.Begin);
                        int hi         = stream.ReadByte();
                        int lo         = stream.ReadByte();
                        int block_size = (hi << 8) | lo;
                        int frame_size = 0x8000;
                        if (hi == 0xFF)
                        {
                            hi         = lo;
                            lo         = (byte)stream.ReadByte();
                            frame_size = (hi << 8) | lo;
                            hi         = (byte)stream.ReadByte();
                            lo         = (byte)stream.ReadByte();
                            block_size = (hi << 8) | lo;
                            pos       += 5;
                        }
                        else
                        {
                            pos += 2;
                        }

                        if (block_size == 0 || frame_size == 0)
                        {
                            break;
                        }

                        int lzxRet = dec.Decompress(stream, block_size, decompressedStream, frame_size);
                        pos          += block_size;
                        decodedBytes += frame_size;
                    }

                    if (decompressedStream.Position != decompressedSize)
                    {
                        throw new ContentLoadException("Decompression of " + originalAssetName + "failed. " +
                                                       " Try decompressing with nativeDecompressXnb first.");
                    }

                    decompressedStream.Seek(0, SeekOrigin.Begin);
                    reader = new ContentReader(this, decompressedStream, this.graphicsDeviceService.GraphicsDevice);
                }
                else
                {
                    reader = new ContentReader(this, stream, this.graphicsDeviceService.GraphicsDevice);
                }

                ContentTypeReaderManager typeManager = new ContentTypeReaderManager(reader);
                reader.TypeReaders = typeManager.LoadAssetReaders(reader);
                foreach (ContentTypeReader r in reader.TypeReaders)
                {
                    r.Initialize(typeManager);
                }
                // we need to read a byte here for things to work out, not sure why
                reader.ReadByte();

                // Get the 1-based index of the typereader we should use to start decoding with
                int index = reader.ReadByte();
                ContentTypeReader contentReader = reader.TypeReaders[index - 1];
                result = reader.ReadObject <T>(contentReader);

                reader.Close();
                stream.Close();
            }
            else
            {
                if ((typeof(T) == typeof(Texture2D)))
                {
                    result = Texture2D.FromFile(graphicsDeviceService.GraphicsDevice, assetName);
                }
                if ((typeof(T) == typeof(SpriteFont)))
                {
                    //result = new SpriteFont(Texture2D.FromFile(graphicsDeviceService.GraphicsDevice,assetName), null, null, null, 0, 0.0f, null, null);
                    throw new NotImplementedException();
                }
                if ((typeof(T) == typeof(Song)))
                {
                    result = new Song(assetName);
                }
                if ((typeof(T) == typeof(SoundEffect)))
                {
                    result = new SoundEffect(assetName);
                }
                if ((typeof(T) == typeof(Video)))
                {
                    result = new Video(assetName);
                }
                if ((typeof(T) == typeof(Effect)))
                {
                    result = new Effect(graphicsDeviceService.GraphicsDevice, assetName);
                }
            }

            if (result == null)
            {
                throw new ContentLoadException("Could not load " + originalAssetName + " asset!");
            }

            return((T)result);
        }
Пример #11
0
        protected T ReadAsset <T>(string assetName, Action <IDisposable> recordDisposableObject, int lod = 0)
        {
            if (string.IsNullOrEmpty(assetName))
            {
                throw new ArgumentNullException("assetName");
            }
            if (disposed)
            {
                throw new ObjectDisposedException("ContentManager");
            }

            //GC.GetTotalMemory(true);
            //Process currentProcess = System.Diagnostics.Process.GetCurrentProcess();
            //long memstart = currentProcess.WorkingSet64;

            string originalAssetName = assetName;
            object result            = null;

            if (this.graphicsDeviceService == null)
            {
                this.graphicsDeviceService = serviceProvider.GetService(typeof(IGraphicsDeviceService)) as IGraphicsDeviceService;
                if (this.graphicsDeviceService == null)
                {
                    throw new InvalidOperationException("No Graphics Device Service");
                }
            }

            // Replace Windows path separators with local path separators
            assetName = GetRealFilename <T>(assetName);

            if (string.IsNullOrEmpty(assetName))
            {
                throw new ContentLoadException("Could not load " + originalAssetName + " asset!");
            }

            if (!Path.HasExtension(assetName))
            {
                assetName = string.Format("{0}.xnb", assetName);
            }

            if (Path.GetExtension(assetName).ToLower() == ".xnb")
            {
                // Load a XNB file
                using (Stream stream = OpenStream(assetName))
                {
                    using (BinaryReader xnbReader = new BinaryReader(stream))
                    {
                        // The first 4 bytes should be the "XNB" header. i use that to detect an invalid file
                        byte[] headerBuffer = new byte[3];
                        xnbReader.Read(headerBuffer, 0, 3);

                        string headerString = Encoding.UTF8.GetString(headerBuffer, 0, 3);

                        byte platform = xnbReader.ReadByte();

                        if (string.Compare(headerString, "XNB") != 0 ||
                            !(platform == 'w' || platform == 'x' || platform == 'm'))
                        {
                            throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?");
                        }

                        ushort version         = xnbReader.ReadUInt16();
                        int    graphicsProfile = version & 0x7f00;
                        version &= 0x80ff;

                        bool compressed = false;
                        if (version == 0x8005 || version == 0x8004)
                        {
                            compressed = true;
                        }
                        else if (version != 5 && version != 4)
                        {
                            throw new ContentLoadException("Invalid XNB version");
                        }

                        // The next int32 is the length of the XNB file
                        int xnbLength = xnbReader.ReadInt32();

                        ContentReader reader;
                        if (compressed)
                        {
                            //decompress the xnb
                            //thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
                            int compressedSize   = xnbLength - 14;
                            int decompressedSize = xnbReader.ReadInt32();
                            int newFileSize      = decompressedSize + 10;

                            MemoryStream decompressedStream = new MemoryStream(decompressedSize);

                            LzxDecoder dec          = new LzxDecoder(16);
                            int        decodedBytes = 0;
                            int        pos          = 0;

                            while (pos < compressedSize)
                            {
                                // let's seek to the correct position
                                stream.Seek(pos + 14, SeekOrigin.Begin);
                                int hi         = stream.ReadByte();
                                int lo         = stream.ReadByte();
                                int block_size = (hi << 8) | lo;
                                int frame_size = 0x8000;
                                if (hi == 0xFF)
                                {
                                    hi         = lo;
                                    lo         = (byte)stream.ReadByte();
                                    frame_size = (hi << 8) | lo;
                                    hi         = (byte)stream.ReadByte();
                                    lo         = (byte)stream.ReadByte();
                                    block_size = (hi << 8) | lo;
                                    pos       += 5;
                                }
                                else
                                {
                                    pos += 2;
                                }

                                if (block_size == 0 || frame_size == 0)
                                {
                                    break;
                                }

                                int lzxRet = dec.Decompress(stream, block_size, decompressedStream, frame_size);
                                pos          += block_size;
                                decodedBytes += frame_size;
                            }

                            if (decompressedStream.Position != decompressedSize)
                            {
                                throw new ContentLoadException("Decompression of " + originalAssetName + "failed. " +
                                                               " Try decompressing with nativeDecompressXnb first.");
                            }

                            decompressedStream.Seek(0, SeekOrigin.Begin);
                            reader = new ContentReader(this, decompressedStream, this.graphicsDeviceService.GraphicsDevice);
                        }
                        else
                        {
                            reader = new ContentReader(this, stream, this.graphicsDeviceService.GraphicsDevice);
                        }

                        using (reader)
                        {
                            ContentTypeReaderManager typeManager = new ContentTypeReaderManager(reader);
                            reader.TypeReaders = typeManager.LoadAssetReaders(reader);
                            foreach (ContentTypeReader r in reader.TypeReaders)
                            {
                                r.Initialize(typeManager);
                            }
                            // we need to read a byte here for things to work out, not sure why
                            reader.ReadByte();

                            // Get the 1-based index of the typereader we should use to start decoding with
                            int index = reader.ReadByte();
                            ContentTypeReader contentReader = reader.TypeReaders[index - 1];
                            result = reader.ReadObject <T>(contentReader);
                        }
                    }
                }
            }
            else
            {
                if ((typeof(T) == typeof(Texture2D)))
                {
                    using (Stream assetStream = OpenStream(assetName))
                    {
                        Texture2D texture = Texture2D.FromFile(graphicsDeviceService.GraphicsDevice, assetStream, lod);
                        texture.Name = originalAssetName;
                        result       = texture;
                    }
                }
                else if ((typeof(T) == typeof(SpriteFont)))
                {
                    //result = new SpriteFont(Texture2D.FromFile(graphicsDeviceService.GraphicsDevice,assetName), null, null, null, 0, 0.0f, null, null);
                    throw new NotImplementedException();
                }
                else if ((typeof(T) == typeof(Song)))
                {
                    result = new Song(assetName);
                }
                else if ((typeof(T) == typeof(SoundEffect)))
                {
                    result = new SoundEffect(assetName);
                }
                else if ((typeof(T) == typeof(Video)))
                {
                    result = new Video(assetName);
                }
                else if ((typeof(T) == typeof(Effect)))
                {
                    result = new Effect(graphicsDeviceService.GraphicsDevice, assetName);
                }
            }

            if (result == null)
            {
                throw new ContentLoadException("Could not load " + originalAssetName + " asset!");
            }

            // Store references to the asset for later use
            T asset = (T)result;

            if (asset is IDisposable)
            {
                if (recordDisposableObject != null)
                {
                    recordDisposableObject(asset as IDisposable);
                }
                else
                {
                    disposableAssets.Add(asset as IDisposable);
                }
            }
            loadedAssets.Add(originalAssetName, asset);

            //GC.GetTotalMemory(true);
            //var memend = currentProcess.WorkingSet64;

            //Console.WriteLine("mem: " + assetName + ", " + (memend -memstart).ToString());

            return((T)result);
        }
Пример #12
0
        protected T ReadAsset<T>(string assetName, Action<IDisposable> recordDisposableObject)
        {
            if (string.IsNullOrEmpty(assetName))
            {
                throw new ArgumentNullException("assetName");
            }
            if (disposed)
            {
                throw new ObjectDisposedException("ContentManager");
            }

            string originalAssetName = assetName;
            object result = null;

            if (this.graphicsDeviceService == null)
            {
                this.graphicsDeviceService = serviceProvider.GetService(typeof(IGraphicsDeviceService)) as IGraphicsDeviceService;
                if (this.graphicsDeviceService == null)
                {
                    throw new InvalidOperationException("No Graphics Device Service");
                }
            }

            // Replace Windows path separators with local path separators
            assetName = GetFilename(assetName);

            // Get the real file name
            if ((typeof(T) == typeof(Curve))) 
            {				
                assetName = CurveReader.Normalize(assetName);
            }
            else if ((typeof(T) == typeof(Texture2D)))
            {
                assetName = Texture2DReader.Normalize(assetName);
            }
            else if ((typeof(T) == typeof(SpriteFont)))
            {
                assetName = SpriteFontReader.Normalize(assetName);
            }
            else if ((typeof(T) == typeof(Effect)))
            {
                assetName = Effect.Normalize(assetName);
            }
            else if ((typeof(T) == typeof(Song)))
            {
                assetName = SongReader.Normalize(assetName);
            }
            else if ((typeof(T) == typeof(SoundEffect)))
            {
                assetName = SoundEffectReader.Normalize(assetName);
            }
            else if ((typeof(T) == typeof(Video)))
            {
                assetName = Video.Normalize(assetName);
            }

            if (string.IsNullOrEmpty(assetName))
            {
                throw new ContentLoadException("Could not load " + originalAssetName + " asset!");
            }

            if (!Path.HasExtension(assetName))
                assetName = string.Format("{0}.xnb", assetName);

            if (Path.GetExtension(assetName).ToLower() == ".xnb")
            {
                // Load a XNB file
                Stream stream = OpenStream(assetName);
                try
                {
                    using (BinaryReader xnbReader = new BinaryReader(stream))
                    {
                        // The first 4 bytes should be the "XNB" header. i use that to detect an invalid file
                        byte x = xnbReader.ReadByte();
                        byte n = xnbReader.ReadByte();
                        byte b = xnbReader.ReadByte();
                        byte platform = xnbReader.ReadByte();

                        if (x != 'X' || n != 'N' || b != 'B' ||
                            !(platform == 'w' || platform == 'x' || platform == 'm'))
                        {
                            throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?");
                        }

                        byte version = xnbReader.ReadByte();
                        byte flags = xnbReader.ReadByte();

                        bool compressed = (flags & 0x80) != 0;
                        if (version != 5 && version != 4)
                        {
                            throw new ContentLoadException("Invalid XNB version");
                        }

                        // The next int32 is the length of the XNB file
                        int xnbLength = xnbReader.ReadInt32();

                        ContentReader reader;
                        if (compressed)
                        {
							
							LzxDecoder dec = new LzxDecoder(16);  							
                            //decompress the xnb
                            //thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor)
                            int compressedSize = xnbLength - 14;
                            int decompressedSize = xnbReader.ReadInt32();
                            int newFileSize = decompressedSize + 10;

                            MemoryStream decompressedStream = new MemoryStream(decompressedSize);

                            int decodedBytes = 0;
                            int pos = 0;							

#if ANDROID
                            // Android native stream does not support the Position property. LzxDecoder.Decompress also uses
                            // Seek.  So we read the entirity of the stream into a memory stream and replace stream with the
                            // memory stream.
                            MemoryStream memStream = new MemoryStream();
                            stream.CopyTo(memStream);
                            memStream.Seek(0, SeekOrigin.Begin);
                            stream.Dispose();
                            stream = memStream;
                            pos = -14;
#endif

                            while (pos < compressedSize)
                            {
                                // let's seek to the correct position
                                // The stream should already be in the correct position, and seeking can be slow
                                stream.Seek(pos + 14, SeekOrigin.Begin);
                                int hi = stream.ReadByte();
                                int lo = stream.ReadByte();
                                int block_size = (hi << 8) | lo;
                                int frame_size = 0x8000;
                                if (hi == 0xFF)
                                {
                                    hi = lo;
                                    lo = (byte)stream.ReadByte();
                                    frame_size = (hi << 8) | lo;
                                    hi = (byte)stream.ReadByte();
                                    lo = (byte)stream.ReadByte();
                                    block_size = (hi << 8) | lo;
                                    pos += 5;
                                }
                                else
                                    pos += 2;

                                if (block_size == 0 || frame_size == 0)
                                    break;

                                int lzxRet = dec.Decompress(stream, block_size, decompressedStream, frame_size);
                                pos += block_size;
                                decodedBytes += frame_size;
                            }

                            if (decompressedStream.Position != decompressedSize)
                            {
                                throw new ContentLoadException("Decompression of " + originalAssetName + "failed. " +
                                                               " Try decompressing with nativeDecompressXnb first.");
                            }

                            decompressedStream.Seek(0, SeekOrigin.Begin);
                            reader = new ContentReader(this, decompressedStream, this.graphicsDeviceService.GraphicsDevice, originalAssetName);
                        }
                        else
                        {
                            reader = new ContentReader(this, stream, this.graphicsDeviceService.GraphicsDevice, originalAssetName);
                        }

                        using (reader)
                        {
                            result = reader.ReadAsset<T>();
                        }
                    }
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Dispose();
                    }
                }
            }
            else
            {
                if ((typeof(T) == typeof(Texture2D)))
                {
#if IPHONE
					Texture2D texture = Texture2D.FromFile(graphicsDeviceService.GraphicsDevice, assetName);
                    texture.Name = originalAssetName;
                    result = texture;
#else
                    using (Stream assetStream = OpenStream(assetName))
                    {
                        Texture2D texture = Texture2D.FromFile(graphicsDeviceService.GraphicsDevice, assetStream);
                        texture.Name = originalAssetName;
                        result = texture;
                    }
#endif
                }
                else if ((typeof(T) == typeof(SpriteFont)))
                {
                    //result = new SpriteFont(Texture2D.FromFile(graphicsDeviceService.GraphicsDevice,assetName), null, null, null, 0, 0.0f, null, null);
                    throw new NotImplementedException();
                }
                else if ((typeof(T) == typeof(Song)))
                {
                    result = new Song(assetName);
                }
                else if ((typeof(T) == typeof(SoundEffect)))
                {
                    result = new SoundEffect(assetName);
                }
                else if ((typeof(T) == typeof(Video)))
                {
                    result = new Video(assetName);
                }
                else if ((typeof(T) == typeof(Effect)))
                {
                    result = new Effect(graphicsDeviceService.GraphicsDevice, assetName);
                }
            }

            if (result == null)
            {
                throw new ContentLoadException("Could not load " + originalAssetName + " asset!");
            }

            if ( recordDisposableObject != null && result is IDisposable )
                recordDisposableObject(result as IDisposable);

            return (T)result;
        }