private static MagickImage Decode(AwesomeReader ar, ImageEncoding encoding, uint bpp, uint mipmap, uint width, uint height, uint bpl, bool ps2Texture = false)
        {
            // Image starts at bottom left corner

            switch (encoding)
            {
            case ImageEncoding.BMP:
                return(DecodeBMP(ar, bpp, width, height, bpl));

            case ImageEncoding.DXT1:
                return(bpp == 8
                        ? DecodeBMP(ar, bpp, width, height, bpl, false)
                        : DecodeDXT(ar, bpp, width, height, encoding));

            case ImageEncoding.DXT5:
            case ImageEncoding.ATI2:
                return(DecodeDXT(ar, bpp, width, height, encoding));
            }

            return(null);
        }
Esempio n. 2
0
        public static Matrix FromStream(AwesomeReader ar)
        {
            // Reads from stream, usually embedded inside milo directories and mesh files
            Matrix mat = new Matrix();

            mat.M11 = ar.ReadSingle(); // M11
            mat.M12 = ar.ReadSingle(); // M12
            mat.M13 = ar.ReadSingle(); // M13

            mat.M21 = ar.ReadSingle(); // M21
            mat.M22 = ar.ReadSingle(); // M22
            mat.M23 = ar.ReadSingle(); // M23

            mat.M31 = ar.ReadSingle(); // M31
            mat.M32 = ar.ReadSingle(); // M32
            mat.M33 = ar.ReadSingle(); // M33

            mat.M41 = ar.ReadSingle(); // M41
            mat.M42 = ar.ReadSingle(); // M42
            mat.M43 = ar.ReadSingle(); // M43
            mat.M44 = 1.0f;            // M44 - Implicit

            return(mat);
        }
Esempio n. 3
0
        public static HMXImage FromStream(Stream input)
        {
            /* Header size = 32 bytes
             * ======================
             * BYTE  - Always 1
             * BYTE  - Bits Per Pixel - Can be 4, 8, 24, or 32 (But usually either 4 or 8)
             * INT32 - Image Format/Encoding
             * BYTE  - MipMaps count
             * INT16 - Width
             * INT16 - Height
             * INT16 - Bytes Per Line
             * BYTES - 19 bytes of zero'd data
             */

            /* Header size = 16 bytes
             * ======================
             * BYTE  - Always 0
             * BYTE  - Bits Per Pixel - Can be 4, 8, 24, or 32 (But usually either 4 or 8)
             * BYTE  - Always 0 (Image Format/Encoding)
             * BYTE  - Awlays 0 MipMaps count
             * INT16 - Width
             * INT16 - Height
             * INT16 - Bytes Per Line
             * BYTES - 6 bytes of zero'd data
             */
            if (input.Position == input.Length)
            {
                return(null);                                // End of stream;
            }
            using (AwesomeReader ar = new AwesomeReader(input))
            {
                ImageEncoding encoding;
                bool          valid;
                uint          bpp, width, height, bpl, mipmap;

                byte firstByte = ar.ReadByte();

                if (firstByte != 0 && firstByte != 1)
                {
                    return(null);
                }

                bpp = ar.ReadByte();

                switch (bpp)
                {
                case 4:
                case 8:
                case 24:
                case 32:
                    break;

                default:
                    return(null);    // Probably should do something else
                }

                if (firstByte == 1)
                {
                    // Guesses endianess
                    ar.BigEndian = DetermineEndianess(ar.ReadBytes(4), out encoding, out valid);
                    if (!valid)
                    {
                        return(null);        // Maybe do something else later
                    }
                    // Reads rest of header
                    mipmap = ar.ReadByte(); // Mipmap count
                }
                else
                {
                    // Xbox OG texture
                    encoding = ImageEncoding.BMP;
                    ar.BaseStream.Position += 2;
                    mipmap = 0;
                }

                width  = ar.ReadUInt16();
                height = ar.ReadUInt16();
                bpl    = ar.ReadUInt16();

                ar.BaseStream.Position += (firstByte == 1) ? 19 : 6;

                // Decodes image
                var      magic = Decode(ar, encoding, bpp, mipmap, width, height, bpl, firstByte == 1);
                HMXImage image = new HMXImage(magic);
                image.Encoding  = encoding;
                image.BigEndian = ar.BigEndian;

                return(image);
            }
        }
        private static MagickImage DecodeDXT(AwesomeReader ar, uint bpp, uint width, uint height, ImageEncoding encoding, bool x360 = true)
        {
            uint   imageSize;
            string compression;

            switch (encoding)
            {
            default:
            case ImageEncoding.DXT1:
                imageSize   = (width * height) / 2;   // 4bpp
                compression = "DXT1";
                break;

            case ImageEncoding.DXT5:
                imageSize   = width * height;   // 8bpp
                compression = "DXT5";
                break;

            case ImageEncoding.ATI2:
                imageSize   = width * height;   // 8bpp
                compression = "ATI2";
                break;
            }

            if (encoding == ImageEncoding.DXT1)
            {
                const int PIXELS_PER_BLOCK = 16;
                int       blockSize        = (PIXELS_PER_BLOCK * (int)bpp) / 8;

                byte[] data = ar.ReadBytes((int)imageSize);
                if (x360)
                {
                    SwapBytes(data);
                }

                Color FromRGB565(int c) => Color.FromArgb(
                    0xFF,
                    (c & 0b1111_1000_0000_0000) >> 8,
                    (c & 0b0000_0111_1110_0000) >> 3,
                    (c & 0b0000_0000_0001_1111) << 3);

                Color MultiplyColor(Color c, float mult) => Color.FromArgb(
                    (int)(c.A * mult),
                    (int)(c.R * mult),
                    (int)(c.G * mult),
                    (int)(c.B * mult));

                Color AddColors(Color a, Color b) => Color.FromArgb(
                    a.A + b.A,
                    a.R + b.R,
                    a.G + b.G,
                    a.B + b.B);

                int idx    = 0;
                var colors = new Color[4];
                var pixels = new Color[16];

                int w, h;
                var imageBytes = new byte[width * height * 4]; // 32-bit color

                for (int y = 0; y < (height >> 2); y++)
                {
                    for (int x = 0; x < (width >> 2); x++)
                    {
                        // Colors - 4 bytes
                        colors[0] = FromRGB565(data[idx] | data[idx + 1] << 8);
                        colors[1] = FromRGB565(data[idx + 2] | data[idx + 3] << 8);
                        colors[2] = AddColors(MultiplyColor(colors[0], 0.66f), MultiplyColor(colors[1], 0.33f));
                        colors[3] = AddColors(MultiplyColor(colors[0], 0.33f), MultiplyColor(colors[1], 0.66f));
                        //colors[2] = AddColors(MultiplyColor(colors[0], 0.5f), MultiplyColor(colors[1], 0.5f));
                        //colors[3] = Color.FromArgb(0);

                        // Indices - 4 bytes (16 pixels)
                        pixels[0] = colors[(data[idx + 4] & 0b00_00_00_11)];       // Row 1