Example #1
0
        private void CreateBannerImage()
        {
            if (bannerBitmap != null)
            {
                bannerBitmap.Dispose();
            }

            ushort[] DecodedImageData = DecodeBNRImage(ImageData); //C4.DecodeC4(ImageData, 96, 32);
            uint[]   PixelData        = new uint[96 * 32];

            for (int i = 0; i < DecodedImageData.Length; i++)
            {
                PixelData[i] = RGB5A3.ToARGB8(DecodedImageData[i]);
            }

            byte[] BitmapSourceData = new byte[4 * 96 * 32];
            for (int i = 0; i < PixelData.Length; i++)
            {
                int idx = i * 4;
                BitmapSourceData[idx + 3] = (byte)((PixelData[i] >> 24) & 0xFF);
                BitmapSourceData[idx + 2] = (byte)((PixelData[i] >> 16) & 0xFF);
                BitmapSourceData[idx + 1] = (byte)((PixelData[i] >> 8) & 0xFF);
                BitmapSourceData[idx + 0] = (byte)((PixelData[i] >> 0) & 0xFF);
            }

            bannerBitmap = BitmapUtilities.CreateBitmap(BitmapSourceData, 96, 32);
            bannerImage  = bannerBitmap.ToBitmapSource();
        }
Example #2
0
        public BTI(int[] Imported_Data, int Width, int Height)
        {
            // Generate "Default" BTI Header (minus Palette & Image/Palette offsets)
            Header = new BTI_Header
            {
                Width  = (ushort)Width,
                Height = (ushort)Height
            };

            // Generate Palette and Convert Image to Palette Index
            List <ushort> Palette_List = new List <ushort>();

            byte[] Converted_Data = new byte[Imported_Data.Length];

            for (int i = 0; i < Imported_Data.Length; i++)
            {
                int    Current_Int = Imported_Data[i];
                ushort Pixel       = RGB5A3.ToRGB5A3((byte)(Current_Int >> 24), (byte)(Current_Int >> 16), (byte)(Current_Int >> 8), (byte)(Current_Int >> 0));
                if (!Palette_List.Contains(Pixel))
                {
                    Palette_List.Add(Pixel);
                }
                int Palette_Idx = Palette_List.IndexOf(Pixel);

                if (Palette_Idx < 0 || Palette_Idx > 255)
                {
                    Console.WriteLine("Palette index was out of bounds!");
                    throw new IndexOutOfRangeException("Palette Index was outside of it's alloted bounds! Value: " + Palette_Idx);
                }

                Converted_Data[i] = (byte)Palette_Idx;
            }

            Palette = Palette_List.ToArray();

            // Turn Converted Data into C8 Encoded Data
            byte[] Encoded_Data = null;
            switch (Header.Image_Format)
            {
            case ImageFormat.C4:
                Encoded_Data = Images.C4.EncodeC4(Imported_Data, Palette, Width, Height, ColorFormat.RGB5A3);
                break;

            case ImageFormat.C8:
                Encoded_Data = Images.C8.EncodeC8(Imported_Data, Palette, Width, Height);
                break;
            }

            // Write Image Offset & Data
            Header.Image_Data_Offset = 0x20;
            Image_Data = Encoded_Data;

            // Write Palette Offset & Count
            Header.Palette_Offset      = (uint)(0x20 + Encoded_Data.Length);
            Header.Palette_Entry_Count = (ushort)Palette.Length;
        }
Example #3
0
        public static uint[] ToArgb8Palette(byte[] data)
        {
            var output = new uint[16];

            for (int i = 0, idx = 0; i < 16; i++, idx += 2)
            {
                output[i] = RGB5A3.ToARGB8((ushort)(data[idx] << 8 | data[idx + 1]));
            }

            return(output);
        }
Example #4
0
        public static uint[] ToArgb8Palette(ushort[] palette)
        {
            var output = new uint[16];

            for (var i = 0; i < 16; i++)
            {
                output[i] = RGB5A3.ToARGB8(palette[i]);
            }

            return(output);
        }
Example #5
0
        private static byte[] C4ImageSubroutineEncode(int[] ImageData, ushort[] Palette, int Width, int Height, bool UsesBlocks = true)
        {
            int[] RGB8Palette = new int[Palette.Length];
            for (int i = 0; i < RGB8Palette.Length; i++)
            {
                RGB8Palette[i] = (int)RGB5A3.ToARGB8(Palette[i]);
            }

            byte[] C4Data = new byte[ImageData.Length];
            for (int i = 0; i < C4Data.Length; i++)
            {
                C4Data[i] = ColorUtilities.ClosestColorRGB(ImageData[i], RGB8Palette);
            }

            return(Utilities.Utilities.CondenseNibbles(UsesBlocks ? BlockFormat.Encode(C4Data, Width, Height, 8, 8) : C4Data));
        }
Example #6
0
        private static byte[] C8ImageSubroutineEncode(int[] ImageData, ushort[] Palette, int Width, int Height)
        {
            int[] RGB8Palette = new int[Palette.Length];
            for (int i = 0; i < RGB8Palette.Length; i++)
            {
                RGB8Palette[i] = (int)RGB5A3.ToARGB8(Palette[i]);
            }

            byte[] C8Data = new byte[ImageData.Length];
            for (int i = 0; i < C8Data.Length; i++)
            {
                C8Data[i] = Utilities.ColorUtilities.ClosestColorRGB(ImageData[i], RGB8Palette);
            }

            return(BlockFormat.Encode(C8Data, Width, Height, 8, 4));
        }
Example #7
0
        public static int[] GetRGBA8Palette(ushort[] rawPalette, ColorFormat colorFormat)
        {
            if (rawPalette == null)
            {
                throw new ArgumentNullException($"{nameof(rawPalette)} cannot be null!");
            }

            var palette = new int[rawPalette.Length];

            switch (colorFormat)
            {
            case ColorFormat.RGB565:
                for (var i = 0; i < palette.Length; i++)
                {
                    palette[i] = (int)RGB565.ToARGB8(rawPalette[i]);
                }

                break;

            case ColorFormat.RGB5A1:
                for (var i = 0; i < palette.Length; i++)
                {
                    palette[i] = (int)RGB5.ToARGB8(rawPalette[i]);
                }

                break;

            case ColorFormat.RGB5A3:
                for (var i = 0; i < palette.Length; i++)
                {
                    palette[i] = (int)RGB5A3.ToARGB8(rawPalette[i]);
                }

                break;

            case ColorFormat.RGBA4:
                for (var i = 0; i < palette.Length; i++)
                {
                    palette[i] = (int)RGBA4.ToARGB8(rawPalette[i]);
                }

                break;
            }

            return(palette);
        }
Example #8
0
        private static int[] C8ImageSubroutineDecode(byte[] C8ImageData, ushort[] Palette, int Width, int Height)
        {
            int[] RGB8Palette = new int[Palette.Length];
            for (int i = 0; i < RGB8Palette.Length; i++)
            {
                RGB8Palette[i] = (int)RGB5A3.ToARGB8(Palette[i]);
            }

            byte[] UnscrambledData = BlockFormat.Decode(C8ImageData, Width, Height, 8, 4);
            int[]  ImageData       = new int[UnscrambledData.Length];

            for (int i = 0; i < ImageData.Length; i++)
            {
                ImageData[i] = RGB8Palette[UnscrambledData[i]];
            }

            return(ImageData);
        }
Example #9
0
        public static int[] Decode(ushort[] rgba16Data, int width, int height)
        {
            var dataOut  = new int[width * height];
            var position = 0;

            rgba16Data = SwizzleUtil.Unswizzle(rgba16Data, width, height, 4, 4);

            for (var y = 0; y < height; y++)
            {
                for (var x = 0; x < width; x++)
                {
                    dataOut[position] = (int)RGB5A3.ToARGB8(rgba16Data[position]);
                    position++;
                }
            }

            return(dataOut);
        }
Example #10
0
        private static int[] C4ImageSubroutineDecode(byte[] C4ImageData, ushort[] Palette, int Width, int Height, bool UsesBlocks = true)
        {
            C4ImageData = Utilities.Utilities.SeparateNibbles(C4ImageData);
            int[] RGB8Palette = new int[Palette.Length];
            for (int i = 0; i < RGB8Palette.Length; i++)
            {
                RGB8Palette[i] = (int)RGB5A3.ToARGB8(Palette[i]);
            }

            byte[] UnscrambledData = UsesBlocks ? BlockFormat.Decode(C4ImageData, Width, Height, 8, 8) : C4ImageData;
            int[]  ImageData       = new int[UnscrambledData.Length];

            for (int i = 0; i < ImageData.Length; i++)
            {
                ImageData[i] = RGB8Palette[UnscrambledData[i]];
            }

            return(ImageData);
        }
Example #11
0
        public BTI(byte[] data)
        {
            Data        = data;
            Header      = new BTI_Header(data);
            Bitmap_Data = new byte[Header.Width * Header.Height * 4];

            if (Header.Image_Format == ImageFormat.RGB565 || Header.Image_Format == ImageFormat.RGB5A3)
            {
                ushort[] PixelData = new ushort[(data.Length - 0x20) / 2];
                for (int i = 0, idx = 0x20; i < PixelData.Length; i++, idx += 2)
                {
                    PixelData[i] = (ushort)((data[idx] << 8) | data[idx + 1]);
                }

                // Decode Block Format
                PixelData = SwizzleUtil.Unswizzle(PixelData, Header.Width, Header.Height, 4, 4);

                Bitmap_Data = new byte[PixelData.Length * 4];
                for (int i = 0, idx = 0; i < PixelData.Length; i++, idx += 4)
                {
                    byte A = 0, R = 0, G = 0, B = 0;
                    if (Header.Image_Format == ImageFormat.RGB5A3)
                    {
                        RGB5A3.ToARGB8(PixelData[i], out A, out R, out G, out B);
                    }
                    else
                    {
                        A = 0xFF;
                        RGB565.ToARGB8(PixelData[i], out R, out G, out B);
                    }

                    Bitmap_Data[idx]     = B;
                    Bitmap_Data[idx + 1] = G;
                    Bitmap_Data[idx + 2] = R;
                    Bitmap_Data[idx + 3] = A;
                }
            }
            else if (Header.Image_Format == ImageFormat.RGBA8)
            {
            }
            else
            {
                switch (Header.Palette_Format)
                {
                case PixelFormat.RGB565:
                case PixelFormat.RGB5A3:
                    Palette = new ushort[Header.Palette_Entry_Count];
                    for (int i = 0; i < Header.Palette_Entry_Count; i++)
                    {
                        int offset = (int)(Header.Palette_Offset + i * 2);
                        Palette[i] = (ushort)((Data[offset] << 8) | Data[offset + 1]);
                    }
                    break;
                }
                switch (Header.Image_Format)
                {
                case ImageFormat.I4:
                    Image_Data = Data.Skip((int)Header.Image_Data_Offset).Take(((Header.Width * Header.Height) + 1) / 2).ToArray();
                    Buffer.BlockCopy(I4.DecodeI4(Image_Data, Header.Width, Header.Height), 0, Bitmap_Data, 0, Bitmap_Data.Length);
                    break;

                case ImageFormat.I8:
                    Image_Data = Data.Skip((int)Header.Image_Data_Offset).Take(Header.Width * Header.Height).ToArray();
                    Buffer.BlockCopy(I8.DecodeI8(Image_Data, Header.Width, Header.Height), 0, Bitmap_Data, 0, Bitmap_Data.Length);
                    break;

                case ImageFormat.IA4:
                    Image_Data = Data.Skip((int)Header.Image_Data_Offset).Take(Header.Width * Header.Height).ToArray();
                    Buffer.BlockCopy(IA4.DecodeIA4(Image_Data, Header.Width, Header.Height, Color.White), 0, Bitmap_Data, 0, Bitmap_Data.Length);
                    break;

                case ImageFormat.IA8:
                    Image_Data = Data.Skip((int)Header.Image_Data_Offset).Take((Header.Width * Header.Height) * 2).ToArray();
                    Buffer.BlockCopy(IA8.DecodeIA8(Image_Data, Header.Width, Header.Height), 0, Bitmap_Data, 0, Bitmap_Data.Length);
                    break;

                case ImageFormat.C4:
                    Image_Data = Data.Skip((int)Header.Image_Data_Offset).Take((Header.Width * Header.Height) / 2).ToArray();
                    Buffer.BlockCopy(C4.DecodeC4(Image_Data, Palette, Header.Width, Header.Height, (ColorFormat)Header.Palette_Format), 0, Bitmap_Data, 0, Bitmap_Data.Length);
                    break;

                case ImageFormat.C8:
                    Image_Data = Data.Skip((int)Header.Image_Data_Offset).Take(Header.Width * Header.Height).ToArray();
                    int Index = 0;

                    for (int blockY = 0; blockY < Header.Height; blockY += 4)
                    {
                        for (int blockX = 0; blockX < Header.Width; blockX += 8)
                        {
                            for (int Y = 0; Y < 4; Y++)
                            {
                                for (int X = 0; X < 8; X++)
                                {
                                    ushort Pixel = Palette[Image_Data[Index]];

                                    int  New_Index = Header.Width * (blockY + Y) + blockX + X;
                                    byte A = 0, R = 0, G = 0, B = 0;
                                    switch (Header.Palette_Format)
                                    {
                                    case PixelFormat.RGB565:
                                        RGB565.ToARGB8(Pixel, out R, out G, out B);
                                        A = 0xFF;
                                        break;

                                    case PixelFormat.RGB5A3:
                                        RGB5A3.ToARGB8(Pixel, out A, out R, out G, out B);
                                        break;

                                    default:
                                        throw new NotImplementedException("Pixel format is not implemented!");
                                    }

                                    Bitmap_Data[New_Index * 4]     = B;
                                    Bitmap_Data[New_Index * 4 + 1] = G;
                                    Bitmap_Data[New_Index * 4 + 2] = R;
                                    Bitmap_Data[New_Index * 4 + 3] = A;

                                    Index++;
                                }
                            }
                        }
                    }
                    break;

                default:
                    throw new NotImplementedException("Image Format is not implemented!");
                }
            }
            Bitmap_Image = Utilities.BitmapUtilities.CreateBitmap(Bitmap_Data, Header.Width, Header.Height);
        }