Ejemplo n.º 1
0
        public static byte[] Encode(System.Drawing.Bitmap bmp, ref byte[] palbin, byte csa = 0)
        {
            int pixelSize = bmp.Width * bmp.Height;

            System.Diagnostics.Debug.WriteLine("TexUt2.Decode: bw = " + (bmp.Width / 128) + "; BH = " + (bmp.Height / 64) + "; type = " + (bmp.PixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed ? "19" : "20") + "; size = " + pixelSize + "; width = " + bmp.Width + "; height = " + bmp.Height);
            switch (bmp.PixelFormat)
            {
            case System.Drawing.Imaging.PixelFormat.Format8bppIndexed:
                csa = 0;
                break;

            case System.Drawing.Imaging.PixelFormat.Format4bppIndexed:
                pixelSize /= 2;
                csa       *= 64;
                break;

            default: throw new NotSupportedException("Unsupported type");
            }
            //Palette
            {
                byte[] destinationArray = new byte[1024];
                for (int i = 0; i < 256; i++)
                {
                    Buffer.BlockCopy(palbin, 4 * i, destinationArray, 4 * (i + tbl[i & 0x7F]), 4);
                }
                System.Drawing.Imaging.ColorPalette palette = bmp.Palette;
                for (int i = 0; i < palette.Entries.Length; i++)
                {
                    int  c    = csa + (i * 4);
                    uint argb = (uint)palette.Entries[i].ToArgb();
                    destinationArray[c + 3] = (byte)Math.Ceiling((double)(argb >> 24) / 2);
                    destinationArray[c]     = (byte)(argb >> 16);
                    destinationArray[c + 1] = (byte)(argb >> 8);
                    destinationArray[c + 2] = (byte)argb;
                }
                for (int i = 0; i < 256; i++)
                {
                    Buffer.BlockCopy(destinationArray, 4 * (i + tbl[i & 0x7F]), palbin, 4 * i, 4);
                }
            }
            //Pixels
            byte[] bin = new byte[pixelSize];
            {
                System.Drawing.Imaging.BitmapData bitmapdata = bmp.LockBits(System.Drawing.Rectangle.FromLTRB(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
                try { System.Runtime.InteropServices.Marshal.Copy(bitmapdata.Scan0, bin, 0, pixelSize); }
                finally { bmp.UnlockBits(bitmapdata); }
            }
            switch (bmp.PixelFormat)
            {
            case System.Drawing.Imaging.PixelFormat.Format8bppIndexed:
                bin = Reform.Encode8(bin, bmp.Width / 128, bmp.Height / 64);
                break;

            case System.Drawing.Imaging.PixelFormat.Format4bppIndexed:
                bin = Reform.Encode4(bin, bmp.Width / 128, bmp.Height / 128);
                break;
            }
            return(bin);
        }
Ejemplo n.º 2
0
        public static System.Drawing.Bitmap Decode(byte[] picbin, byte[] palbin, uint type, ushort width, ushort height, byte csa = 0)
        {
            System.Drawing.Imaging.PixelFormat pf;
            System.Diagnostics.Debug.WriteLine("TexUt2.Decode: bw = " + (width / 128) + "; BH = " + (height / 64) + "; type = " + type + "; size = " + picbin.Length + "; width = " + width + "; height = " + height);
            switch (type)
            {
            case 19:
                pf     = System.Drawing.Imaging.PixelFormat.Format8bppIndexed;
                picbin = Reform.Decode8(picbin, width / 128, height / 64);
                break;

            case 20:
                pf     = System.Drawing.Imaging.PixelFormat.Format4bppIndexed;
                picbin = Reform.Decode4(picbin, width / 128, height / 128);
                break;

            default: throw new NotSupportedException("Unsupported image type.");
            }
            System.Drawing.Bitmap pic = new System.Drawing.Bitmap(width, height, pf);
            {
                System.Drawing.Imaging.BitmapData bitmapdata = pic.LockBits(System.Drawing.Rectangle.FromLTRB(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, pf);
                try { System.Runtime.InteropServices.Marshal.Copy(picbin, 0, bitmapdata.Scan0, Math.Min(picbin.Length, bitmapdata.Stride * height)); }
                finally { pic.UnlockBits(bitmapdata); }
            }
            /*The palette is swizzled, or something...*/
            {
                byte[] destinationArray = new byte[1024];
                for (int i = 0; i < 256; i++)
                {
                    Buffer.BlockCopy(palbin, 4 * i, destinationArray, 4 * (i + tbl[i & 0x7F]), 4);
                }
                Buffer.BlockCopy(destinationArray, 0, palbin, 0, 1024);
            }
            type = 0;
            System.Drawing.Imaging.ColorPalette palette = pic.Palette;
            switch (pf)
            {
            case System.Drawing.Imaging.PixelFormat.Format8bppIndexed:
                type = 256;
                csa  = 0;
                break;

            case System.Drawing.Imaging.PixelFormat.Format4bppIndexed:
                type = 16;
                csa *= 64;
                break;
            }
            for (int i = 0; i < type; i++)
            {
                int c = csa + (i * 4);
                //Because of rounding, when reading values back use Math.Ceiling(input/2)
                palette.Entries[i] = System.Drawing.Color.FromArgb((int)Math.Min(palbin[c + 3] * 2, 255), palbin[c], palbin[c + 1], palbin[c + 2]);
            }
            pic.Palette = palette;
            return(pic);
        }
Ejemplo n.º 3
0
        private static void setData(BinaryReader br, long baseP, byte[] data)
        {
            ulong num  = br.ReadUInt64();
            int   bw   = ((int)(num >> 0x30)) & 0x3F;
            uint  type = ((uint)(num >> 0x38)) & 0x3F;

            br.BaseStream.Position += 8 + 16 + 16 + 16;
            int size = (br.ReadUInt16() & 0x7FFF) << 4;

            br.BaseStream.Position += 0x12L;
            br.BaseStream.Position  = baseP + br.ReadInt32();

            Debug.WriteLine("writing:bw = " + bw + "; type = " + type + "; size = " + size);
            int ds = size / 8192;

            switch (type)
            {
            case 0:
                if (bw > 0)
                {
                    data = Reform.Decode32(data, bw, ds / bw);
                }
                break;

            case 19:
                bw /= 2;
                if (bw > 0)
                {
                    data = Reform.Decode8(data, bw, ds / bw);
                }
                break;

            case 20:
                bw /= 2;
                if (bw > 0)
                {
                    data = Reform.Decode4(data, bw, ds / bw);
                }
                break;

            default:
                throw new NotSupportedException("Unknown type: " + type);
            }
            Debug.WriteLine("Writing " + size + " bytes...");
            Debug.WriteLineIf(size < data.Length, "Expected " + size + " bytes, but got " + data.Length + " bytes; Truncating!");
            Debug.WriteLineIf(size > data.Length, "Expected " + size + " bytes, but only got " + data.Length + " bytes!");
            br.BaseStream.Write(data, 0, Math.Min(size, (int)Math.Min(data.Length, br.BaseStream.Length - br.BaseStream.Position)));
        }
Ejemplo n.º 4
0
        private static byte[] getDataRF(BinaryReader br, long baseP, out long ramOffset, out long fileOffset)
        {
            ulong num = br.ReadUInt64();

            ramOffset = 256u * (((uint)(num >> 0x20)) & 0x3FFFu);
            int  bw   = ((int)(num >> 0x30)) & 0x3F;
            uint type = ((uint)(num >> 0x38)) & 0x3F;

#if TRACE
            br.BaseStream.Position += 8;
            Trace.Assert((num & 0x3fff) == 0);
            Trace.Assert(((num >> 16) & 0x3f) == 0);
            Trace.Assert(((num >> 0x18) & 0x3f) == 0);
            num = br.ReadUInt64();
            br.BaseStream.Position += 8;
            Trace.Assert((num & 0x7ff) == 0);
            Trace.Assert(((num >> 0x10) & 0x7ff) == 0);
            Trace.Assert(((num >> 0x20) & 0x7ff) == 0);
            Trace.Assert(((num >> 0x30) & 0x7ff) == 0);
            Trace.Assert(((num >> 0x3b) & 3) == 0);
            br.BaseStream.Position += 16;
            Trace.Assert((br.ReadUInt64() & 2) == 0);
            br.BaseStream.Position += 8;
#else
            br.BaseStream.Position += 8 + 16 + 16 + 16;
#endif
            int size = (br.ReadUInt16() & 0x7FFF) << 4;
            br.BaseStream.Position += 0x12L;
            br.BaseStream.Position  = fileOffset = baseP + br.ReadInt32();
            byte[] buffer = new byte[size];
            Debug.WriteLine("Reading " + size + " bytes...");
#if DEBUG
            {
                int t = br.BaseStream.Read(buffer, 0, size);
                Debug.WriteLineIf(t != size, "Expected " + size + " bytes, but only got " + t + " bytes!");
            }
#else
            br.BaseStream.Read(buffer, 0, size);
#endif
            Debug.WriteLine("bw = " + bw + "; type = " + type + "; size = " + size);
            size /= 8192;
            switch (type)
            {
            case 0:
                if (bw > 0)
                {
                    buffer = Reform.Encode32(buffer, bw, size / bw);
                }
                break;

            case 19:
                bw /= 2;
                if (bw > 0)
                {
                    buffer = Reform.Encode8(buffer, bw, size / bw);
                }
                break;

            case 20:
                bw /= 2;
                if (bw > 0)
                {
                    buffer = Reform.Encode4(buffer, bw, size / bw);
                }
                break;

            default:
                throw new NotSupportedException("Unknown type: " + type);
            }
            return(buffer);
        }
Ejemplo n.º 5
0
        private void parseD(long pos, long len, int index)
        {
            if (pos + len > this.file.BaseStream.Length)
            {
                throw new IndexOutOfRangeException("IMGD goes past file bounds");
            }
            this.file.Seek(pos, SeekOrigin.Begin);
            if (this.file.ReadUInt32() != 0x44474D49)
            {
                throw new InvalidDataException("IMGD has bad signature");
            }
#if DEBUG
            uint   pixelOffset, pixelLength, paletteOffset, paletteLength;
            ushort width, height, type;
            byte   encode;
            Debug.WriteLine(String.Format("---IMGD---\nN0: {0}\npixelOffset: {1}\npixelLength: {2}\npaletteOffset: {3}\npaletteLength: {4}\nN5: {5}\nN6: {6}\nwidth: {7}\nheight: {8}\nN9: {9}\nN10: {10}\ntype: {11}\nN12: {12}\nN13: {13}\nN14: {14}\nN15: {15}\nN16: {16}\nencode: {17}\n---IMGD End---",
                                          this.file.ReadUInt32(),
                                          pixelOffset   = this.file.ReadUInt32(),
                                          pixelLength   = this.file.ReadUInt32(),
                                          paletteOffset = this.file.ReadUInt32(),
                                          paletteLength = this.file.ReadUInt32(),
                                          this.file.ReadUInt16(),
                                          this.file.ReadUInt16(),
                                          width  = this.file.ReadUInt16(),
                                          height = this.file.ReadUInt16(),
                                          this.file.ReadUInt32(),
                                          this.file.ReadUInt16(),
                                          type = this.file.ReadUInt16(),
                                          this.file.ReadUInt32(),
                                          this.file.ReadUInt32(),
                                          this.file.ReadUInt32(),
                                          this.file.ReadUInt32(),
                                          this.file.ReadUInt32(),
                                          encode = this.file.ReadByte()
                                          ));
#else
            this.file.Seek(4, SeekOrigin.Current);
            uint pixelOffset   = this.file.ReadUInt32(),
                 pixelLength   = this.file.ReadUInt32(),
                 paletteOffset = this.file.ReadUInt32(),
                 paletteLength = this.file.ReadUInt32();
            this.file.Seek(4, SeekOrigin.Current);
            ushort width  = this.file.ReadUInt16(),
                   height = this.file.ReadUInt16();
            this.file.Seek(6, SeekOrigin.Current);
            ushort type = this.file.ReadUInt16();
            this.file.Seek(20, SeekOrigin.Current);
            byte encode = this.file.ReadByte();
#endif
            if (pixelOffset + pixelLength > len)
            {
                throw new IndexOutOfRangeException("IMGD pixel data goes past file bounds");
            }
            if (paletteOffset + paletteLength > len)
            {
                throw new IndexOutOfRangeException("IMGD palette data goes past file bounds");
            }

            PixelFormat pf;
            switch (type)
            {
            case 19: pf = PixelFormat.Format8bppIndexed; break;

            case 20: pf = PixelFormat.Format4bppIndexed; break;

            default: throw new NotSupportedException("Unsupported IMGD type");
            }
            Bitmap bmp = new Bitmap(width, height, pf);
            {
                this.file.Seek(pos + pixelOffset, SeekOrigin.Begin);
                byte[] buffer = this.file.ReadBytes((int)pixelLength);
                switch (pf)
                {
                case PixelFormat.Format8bppIndexed:
                    if (encode == 7)
                    {
                        buffer = Reform.Decode8(Reform.Encode32(buffer, width / 128, height / 64), width / 128, height / 64);
                    }
                    break;

                case PixelFormat.Format4bppIndexed:
                    if (encode == 7)
                    {
                        buffer = Reform.Decode4(Reform.Encode32(buffer, width / 128, height / 128), width / 128, height / 128);
                    }
                    else
                    {
                        Reform.swapHLUT(buffer);
                    }
                    break;
                }
                BitmapData pix = bmp.LockBits(System.Drawing.Rectangle.FromLTRB(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, pf);
                try { System.Runtime.InteropServices.Marshal.Copy(buffer, 0, pix.Scan0, (int)pixelLength); }
                finally { bmp.UnlockBits(pix); }
            }
            {
                this.file.Seek(pos + paletteOffset, SeekOrigin.Begin);
                byte[]       buffer  = this.file.ReadBytes((int)paletteLength);
                ColorPalette palette = bmp.Palette;
                //Because of rounding, when reading values back use Math.Ceiling(input/2)
                switch (pf)
                {
                case PixelFormat.Format8bppIndexed:
                    for (int i = 0; i < 256; i++)
                    {
                        palette.Entries[Reform.paletteSwap34(i)] = Color.FromArgb((int)Math.Min(buffer[(i * 4) + 3] * 2, 255), buffer[i * 4], buffer[(i * 4) + 1], buffer[(i * 4) + 2]);
                        Debug.WriteLineIf(buffer[(i * 4) + 3] > 128, "Transparency before transform is over 128: " + buffer[(i * 4) + 3]);
                    }
                    break;

                case PixelFormat.Format4bppIndexed:
                    for (int i = 0; i < 16; i++)
                    {
                        palette.Entries[i] = Color.FromArgb((int)Math.Min(buffer[(i * 4) + 3] * 2, 255), buffer[i * 4], buffer[(i * 4) + 1], buffer[(i * 4) + 2]);
                        Debug.WriteLineIf(buffer[(i * 4) + 3] > 128, "Transparency before transform is over 128: " + buffer[(i * 4) + 3]);
                    }
                    break;
                }
                bmp.Palette = palette;
            }
            this.bmps.Add(bmp);
        }
Ejemplo n.º 6
0
        protected override void setBMPInternal(int index, ref Bitmap bmp)
        {
            if (!this.file.CanWrite)
            {
                throw new NotSupportedException("Stream is readonly.");
            }
            long pos = getIMGDOffset(index);

            this.file.Seek(pos, SeekOrigin.Begin);
            if (this.file.ReadUInt32() != 0x44474D49)
            {
                throw new InvalidDataException("IMGD has bad signature.");
            }
            this.file.Seek(4, SeekOrigin.Current);
            uint pixelOffset   = this.file.ReadUInt32(),
                 pixelLength   = this.file.ReadUInt32(),
                 paletteOffset = this.file.ReadUInt32(),
                 paletteLength = this.file.ReadUInt32();

            this.file.Seek(4, SeekOrigin.Current);
            ushort width  = this.file.ReadUInt16(),
                   height = this.file.ReadUInt16();

            this.file.Seek(6, SeekOrigin.Current);
            ushort type = this.file.ReadUInt16();

            this.file.Seek(20, SeekOrigin.Current);
            byte encode = this.file.ReadByte();

            if (bmp.Width != width || bmp.Height != height)
            {
                throw new NotSupportedException("New image has different dimensions.");
            }
            PixelFormat pf;

            switch (type)
            {
            case 19: pf = PixelFormat.Format8bppIndexed; break;

            case 20: pf = PixelFormat.Format4bppIndexed; break;

            default: throw new NotSupportedException("Unsupported IMGD type");
            }
            if (bmp.PixelFormat != pf)
            {
                requestQuantize(ref bmp, pf);
            }
            {
                BitmapData pix    = bmp.LockBits(System.Drawing.Rectangle.FromLTRB(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, pf);
                byte[]     buffer = new byte[pixelLength];
                try { System.Runtime.InteropServices.Marshal.Copy(pix.Scan0, buffer, 0, (int)pixelLength); }
                finally { bmp.UnlockBits(pix); }
                switch (pf)
                {
                case PixelFormat.Format8bppIndexed:
                    if (encode == 7)
                    {
                        buffer = Reform.Decode32(Reform.Encode8(buffer, width / 128, height / 64), width / 128, height / 64);
                    }
                    break;

                case PixelFormat.Format4bppIndexed:
                    if (encode == 7)
                    {
                        buffer = Reform.Decode32(Reform.Encode4(buffer, width / 128, height / 128), width / 128, height / 128);
                    }
                    else
                    {
                        Reform.swapHLUT(buffer);
                    }
                    break;
                }
                this.file.Seek(pos + pixelOffset, SeekOrigin.Begin);
                this.file.Write(buffer, 0, (int)pixelLength);
            }
            {
                ColorPalette palette = bmp.Palette;
                byte[]       buffer  = new byte[paletteLength];
                switch (pf)
                {
                case PixelFormat.Format8bppIndexed:
                    for (int i = 0; i < 256; i++)
                    {
                        uint argb = (uint)palette.Entries[Reform.paletteSwap34(i)].ToArgb();
                        buffer[(i * 4) + 3] = (byte)Math.Ceiling((double)(argb >> 24) / 2);
                        buffer[i * 4]       = (byte)(argb >> 16);
                        buffer[i * 4 + 1]   = (byte)(argb >> 8);
                        buffer[i * 4 + 2]   = (byte)argb;
                    }
                    break;

                case PixelFormat.Format4bppIndexed:
                    for (int i = 0; i < 16; i++)
                    {
                        uint argb = (uint)palette.Entries[i].ToArgb();
                        buffer[(i * 4) + 3] = (byte)Math.Ceiling((double)(argb >> 24) / 2);
                        buffer[i * 4]       = (byte)(argb >> 16);
                        buffer[i * 4 + 1]   = (byte)(argb >> 8);
                        buffer[i * 4 + 2]   = (byte)argb;
                    }
                    break;
                }
                this.file.Seek(pos + paletteOffset, SeekOrigin.Begin);
                this.file.Write(buffer, 0, (int)paletteLength);
            }
        }