Beispiel #1
0
        public static PALETTE_FORMAT ToGenericPaletteFormat(PaletteFormats Format)
        {
            switch (Format)
            {
            case PaletteFormats.IA8: return(PALETTE_FORMAT.IA8);

            case PaletteFormats.RGB565: return(PALETTE_FORMAT.RGB565);

            case PaletteFormats.RGB5A3: return(PALETTE_FORMAT.RGB5A3);

            default:
                throw new Exception("Unknown Palette Format " + Format);
            }
        }
Beispiel #2
0
        private static Tuple <byte[], ushort[]> EncodeC4(PaletteFormats PaletteFormat, byte[] m_rgbaImageData, int Width, int Height)
        {
            List <Color32> palColors = new List <Color32>();

            uint numBlocksW = (uint)Width / 8;
            uint numBlocksH = (uint)Height / 8;

            byte[] pixIndices = new byte[numBlocksH * numBlocksW * 8 * 8];

            for (int i = 0; i < (Width * Height) * 4; i += 4)
            {
                palColors.Add(new Color32(m_rgbaImageData[i + 2], m_rgbaImageData[i + 1], m_rgbaImageData[i + 0], m_rgbaImageData[i + 3]));
            }

            List <ushort> rawColorData = new List <ushort>();
            Dictionary <Color32, byte> pixelColorIndexes = new Dictionary <Color32, byte>();

            foreach (Color32 col in palColors)
            {
                EncodeColor(PaletteFormat, col, rawColorData, pixelColorIndexes);
            }

            int pixIndex = 0;

            for (int yBlock = 0; yBlock < numBlocksH; yBlock++)
            {
                for (int xBlock = 0; xBlock < numBlocksW; xBlock++)
                {
                    for (int pY = 0; pY < 8; pY++)
                    {
                        for (int pX = 0; pX < 8; pX += 2)
                        {
                            byte color1 = (byte)(pixelColorIndexes[palColors[Width * ((yBlock * 8) + pY) + (xBlock * 8) + pX]] & 0xF);
                            byte color2 = (byte)(pixelColorIndexes[palColors[Width * ((yBlock * 8) + pY) + (xBlock * 8) + pX + 1]] & 0xF);
                            pixIndices[pixIndex]    = (byte)(color1 << 4);
                            pixIndices[pixIndex++] |= color2;
                        }
                    }
                }
            }

            //   PaletteCount = (ushort)rawColorData.Count;
            //  PalettesEnabled = true;

            return(new Tuple <byte[], ushort[]>(pixIndices, rawColorData.ToArray()));
        }
        private static byte[] DecodeC8(EndianBinaryReader stream, uint width, uint height, Palette imagePalette, PaletteFormats paletteFormat)
        {
            //4 bpp, 8 block width/4 block height, block size 32 bytes, possible palettes (IA8, RGB565, RGB5A3)
            uint numBlocksW = width / 8;
            uint numBlocksH = height / 4;

            byte[] decodedData = new byte[width * height * 8];

            //Read the indexes from the file
            for (int yBlock = 0; yBlock < numBlocksH; yBlock++)
            {
                for (int xBlock = 0; xBlock < numBlocksW; xBlock++)
                {
                    //Inner Loop for pixels
                    for (int pY = 0; pY < 4; pY++)
                    {
                        for (int pX = 0; pX < 8; pX++)
                        {
                            //Ensure we're not reading past the end of the image.
                            if ((xBlock * 8 + pX >= width) || (yBlock * 4 + pY >= height))
                                continue;

                            byte data = stream.ReadByte();
                            decodedData[width * ((yBlock * 4) + pY) + (xBlock * 8) + pX] = data;
                        }
                    }
                }
            }

            //Now look them up in the palette and turn them into actual colors.
            byte[] finalDest = new byte[decodedData.Length / 2];

            int pixelSize = paletteFormat == PaletteFormats.IA8 ? 2 : 4;
            int destOffset = 0;
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    UnpackPixelFromPalette(decodedData[y * width + x], ref finalDest, destOffset, imagePalette.GetBytes(), paletteFormat);
                    destOffset += pixelSize;
                }
            }

            return finalDest;
        }
Beispiel #4
0
        private static void UnpackPixelFromPalette(int paletteIndex, ref byte[] dest, int offset, byte[] paletteData, PaletteFormats format)
        {
            switch (format)
            {
            case PaletteFormats.IA8:
                dest[0] = paletteData[2 * paletteIndex + 1];
                dest[1] = paletteData[2 * paletteIndex + 0];
                break;

            case PaletteFormats.RGB565:
            {
                ushort palettePixelData = (ushort)((Buffer.GetByte(paletteData, 2 * paletteIndex) << 8) | Buffer.GetByte(paletteData, 2 * paletteIndex + 1));
                RGB565ToRGBA8(palettePixelData, ref dest, offset);
            }
            break;

            case PaletteFormats.RGB5A3:
            {
                ushort palettePixelData = (ushort)((Buffer.GetByte(paletteData, 2 * paletteIndex) << 8) | Buffer.GetByte(paletteData, 2 * paletteIndex + 1));
                RGB5A3ToRGBA8(palettePixelData, ref dest, offset);
            }
            break;
            }
        }
Beispiel #5
0
        private static byte[] DecodeC8(FileReader stream, uint width, uint height, Palette imagePalette, PaletteFormats paletteFormat)
        {
            //4 bpp, 8 block width/4 block height, block size 32 bytes, possible palettes (IA8, RGB565, RGB5A3)
            uint numBlocksW = width / 8;
            uint numBlocksH = height / 4;

            byte[] decodedData = new byte[width * height * 8];

            //Read the indexes from the file
            for (int yBlock = 0; yBlock < numBlocksH; yBlock++)
            {
                for (int xBlock = 0; xBlock < numBlocksW; xBlock++)
                {
                    //Inner Loop for pixels
                    for (int pY = 0; pY < 4; pY++)
                    {
                        for (int pX = 0; pX < 8; pX++)
                        {
                            //Ensure we're not reading past the end of the image.
                            if ((xBlock * 8 + pX >= width) || (yBlock * 4 + pY >= height))
                            {
                                continue;
                            }


                            byte data = stream.ReadByte();
                            decodedData[width * ((yBlock * 4) + pY) + (xBlock * 8) + pX] = data;
                        }
                    }
                }
            }

            //Now look them up in the palette and turn them into actual colors.
            byte[] finalDest = new byte[decodedData.Length / 2];

            int pixelSize  = paletteFormat == PaletteFormats.IA8 ? 2 : 4;
            int destOffset = 0;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    UnpackPixelFromPalette(decodedData[y * width + x], ref finalDest, destOffset, imagePalette.GetBytes(), paletteFormat);
                    destOffset += pixelSize;
                }
            }

            return(finalDest);
        }
Beispiel #6
0
        private static byte[] DecodeData(FileReader stream, uint width, uint height, TextureFormats format, Palette imagePalette, PaletteFormats paletteFormat)
        {
            stream.SetByteOrder(true);

            switch (format)
            {
            case TextureFormats.I4:
                return(DecodeI4(stream, width, height));

            case TextureFormats.I8:
                return(DecodeI8(stream, width, height));

            case TextureFormats.IA4:
                return(DecodeIA4(stream, width, height));

            case TextureFormats.IA8:
                return(DecodeIA8(stream, width, height));

            case TextureFormats.RGB565:
                return(DecodeRgb565(stream, width, height));

            case TextureFormats.RGB5A3:
                return(DecodeRgb5A3(stream, width, height));

            case TextureFormats.RGBA32:
                return(DecodeRgba32(stream, width, height));

            case TextureFormats.C4:
                return(DecodeC4(stream, width, height, imagePalette, paletteFormat));

            case TextureFormats.C8:
                return(DecodeC8(stream, width, height, imagePalette, paletteFormat));

            case TextureFormats.CMPR:
                return(DecodeCmpr(stream, width, height));

            case TextureFormats.C14X2:
            default:
                Console.WriteLine("Unsupported Binary Texture Image format {0}, unable to decode!", format);
                return(new byte[0]);
            }
        }
Beispiel #7
0
        public static byte[] DecodeData(byte[] ImageData, byte[] PaletteData, uint width, uint height, TextureFormats format, PaletteFormats palleteFormat)
        {
            Palette Palette = new Palette();

            Palette.Load(PaletteData);

            return(DecodeData(new FileReader(ImageData), width, height, format, Palette, palleteFormat));
        }
Beispiel #8
0
        public static Tuple <List <byte[]>, ushort[]> GenerateMipList(Bitmap Image, uint TexWidth, uint TexHeight,
                                                                      uint MipCount, TextureFormats Format, PaletteFormats PaletteFormat)
        {
            ushort[] paletteData = new ushort[0];

            List <byte[]> mipmaps = new List <byte[]>();

            for (int mipLevel = 0; mipLevel < MipCount; mipLevel++)
            {
                int MipWidth  = Math.Max(1, (int)TexWidth >> mipLevel);
                int MipHeight = Math.Max(1, (int)TexHeight >> mipLevel);

                if (mipLevel != 0)
                {
                    Image = BitmapExtension.Resize(Image, MipWidth, MipHeight);
                }

                var EncodedData = Decode_Gamecube.EncodeData(BitmapExtension.ImageToByte(Image), Format, PaletteFormat, MipWidth, MipHeight);

                mipmaps.Add(EncodedData.Item1);

                if (mipLevel == 0) //Set palette data once
                {
                    paletteData = EncodedData.Item2;
                }
            }
            Image.Dispose();

            return(Tuple.Create(mipmaps, paletteData));
        }
Beispiel #9
0
        private static void EncodeColor(PaletteFormats PaletteFormat, Color32 col, List <ushort> rawColorData, Dictionary <Color32, byte> pixelColorIndexes)
        {
            switch (PaletteFormat)
            {
            case PaletteFormats.IA8:
                byte i = (byte)((col.R * 0.2126) + (col.G * 0.7152) + (col.B * 0.0722));

                ushort fullIA8 = (ushort)((i << 8) | (col.A));
                if (!rawColorData.Contains(fullIA8))
                {
                    rawColorData.Add(fullIA8);
                }
                if (!pixelColorIndexes.ContainsKey(col))
                {
                    pixelColorIndexes.Add(col, (byte)rawColorData.IndexOf(fullIA8));
                }
                break;

            case PaletteFormats.RGB565:
                ushort r_565 = (ushort)(col.R >> 3);
                ushort g_565 = (ushort)(col.G >> 2);
                ushort b_565 = (ushort)(col.B >> 3);

                ushort fullColor565 = 0;
                fullColor565 |= b_565;
                fullColor565 |= (ushort)(g_565 << 5);
                fullColor565 |= (ushort)(r_565 << 11);

                if (!rawColorData.Contains(fullColor565))
                {
                    rawColorData.Add(fullColor565);
                }
                if (!pixelColorIndexes.ContainsKey(col))
                {
                    pixelColorIndexes.Add(col, (byte)rawColorData.IndexOf(fullColor565));
                }
                break;

            case PaletteFormats.RGB5A3:
                ushort r_53 = (ushort)(col.R >> 4);
                ushort g_53 = (ushort)(col.G >> 4);
                ushort b_53 = (ushort)(col.B >> 4);
                ushort a_53 = (ushort)(col.A >> 5);

                ushort fullColor53 = 0;
                fullColor53 |= b_53;
                fullColor53 |= (ushort)(g_53 << 4);
                fullColor53 |= (ushort)(r_53 << 8);
                fullColor53 |= (ushort)(a_53 << 12);

                if (!rawColorData.Contains(fullColor53))
                {
                    rawColorData.Add(fullColor53);
                }
                if (!pixelColorIndexes.ContainsKey(col))
                {
                    pixelColorIndexes.Add(col, (byte)rawColorData.IndexOf(fullColor53));
                }
                break;
            }
        }
Beispiel #10
0
        public static Tuple <byte[], ushort[]> EncodeFromBitmap(System.Drawing.Bitmap bitmap, TextureFormats Format, PaletteFormats PaletteFormat = PaletteFormats.RGB565)
        {
            byte[] m_rgbaImageData = new byte[bitmap.Width * bitmap.Height * 4];

            int width  = bitmap.Width;
            int height = bitmap.Height;

            BitmapData dat = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            Marshal.Copy(dat.Scan0, m_rgbaImageData, 0, m_rgbaImageData.Length);
            bitmap.UnlockBits(dat);
            bitmap.Dispose();

            return(EncodeData(m_rgbaImageData, Format, PaletteFormat, width, height));
        }
Beispiel #11
0
        public static Tuple <byte[], ushort[]> EncodeData(byte[] m_rgbaImageData, TextureFormats Format, PaletteFormats PaletteFormat, int Width, int Height)
        {
            switch (Format)
            {
            case TextureFormats.I4:
                return(new Tuple <byte[], ushort[]>(ImageDataFormat.I4.ConvertTo(m_rgbaImageData, Width, Height, null), new ushort[0]));

            case TextureFormats.I8:
                return(new Tuple <byte[], ushort[]>(ImageDataFormat.I8.ConvertTo(m_rgbaImageData, Width, Height, null), new ushort[0]));

            case TextureFormats.IA4:
                return(new Tuple <byte[], ushort[]>(ImageDataFormat.IA4.ConvertTo(m_rgbaImageData, Width, Height, null), new ushort[0]));

            case TextureFormats.IA8:
                return(new Tuple <byte[], ushort[]>(ImageDataFormat.IA8.ConvertTo(m_rgbaImageData, Width, Height, null), new ushort[0]));

            case TextureFormats.RGB565:
                return(new Tuple <byte[], ushort[]>(ImageDataFormat.RGB565.ConvertTo(m_rgbaImageData, Width, Height, null), new ushort[0]));

            case TextureFormats.RGB5A3:
                return(new Tuple <byte[], ushort[]>(ImageDataFormat.RGB5A3.ConvertTo(m_rgbaImageData, Width, Height, null), new ushort[0]));

            case TextureFormats.RGBA32:
                return(new Tuple <byte[], ushort[]>(ImageDataFormat.Rgba32.ConvertTo(m_rgbaImageData, Width, Height, null), new ushort[0]));

            case TextureFormats.C4:
                return(EncodeC4(PaletteFormat, m_rgbaImageData, Width, Height));

            case TextureFormats.C8:
                return(EncodeC8(PaletteFormat, m_rgbaImageData, Width, Height));

            case TextureFormats.CMPR:
                return(new Tuple <byte[], ushort[]>(ImageDataFormat.Cmpr.ConvertTo(m_rgbaImageData, Width, Height, null), new ushort[0]));

            default:
                return(new Tuple <byte[], ushort[]>(new byte[0], new ushort[0]));
            }
        }
Beispiel #12
0
        private static byte[] DecodeData(EndianBinaryReader stream, uint width, uint height, TextureFormats format, Palette imagePalette, PaletteFormats paletteFormat)
        {
            switch (format)
            {
            case TextureFormats.I4:
                return(DecodeI4(stream, width, height));

            case TextureFormats.I8:
                return(DecodeI8(stream, width, height));

            case TextureFormats.IA4:
                return(DecodeIA4(stream, width, height));

            case TextureFormats.IA8:
                return(DecodeIA8(stream, width, height));

            case TextureFormats.RGB565:
                return(DecodeRgb565(stream, width, height));

            case TextureFormats.RGB5A3:
                return(DecodeRgb5A3(stream, width, height));

            case TextureFormats.RGBA32:
                return(DecodeRgba32(stream, width, height));

            case TextureFormats.C4:
                return(DecodeC4(stream, width, height, imagePalette, paletteFormat));

            case TextureFormats.C8:
                return(DecodeC8(stream, width, height, imagePalette, paletteFormat));

            case TextureFormats.CMPR:
                return(DecodeCmpr(stream, width, height));

            case TextureFormats.C14X2:
            default:
                WLog.Warning(LogCategory.Textures, null, "Unsupported Binary Texture Image format {0}, unable to decode!", format);
                return(new byte[0]);
            }
        }
Beispiel #13
0
        private static byte[] DecodeC4(FileReader stream, uint width, uint height, Palette imagePalette, PaletteFormats paletteFormat)
        {
            stream.SetByteOrder(true);

            //4 bpp, 8 block width/height, block size 32 bytes, possible palettes (IA8, RGB565, RGB5A3)
            uint numBlocksW = (width + 7) / 8;
            uint numBlocksH = (height + 7) / 8;

            byte[] decodedData = new byte[width * height * 8];

            //Read the indexes from the file
            for (int yBlock = 0; yBlock < numBlocksH; yBlock++)
            {
                for (int xBlock = 0; xBlock < numBlocksW; xBlock++)
                {
                    //Inner Loop for pixels
                    for (int pY = 0; pY < 8; pY++)
                    {
                        for (int pX = 0; pX < 8; pX += 2)
                        {
                            if ((xBlock * 8 + pX >= width) || (yBlock * 8 + pY >= height))
                            {
                                stream.Seek(1);
                                continue;
                            }

                            byte data = stream.ReadByte();
                            byte t    = (byte)(data & 0xF0);
                            byte t2   = (byte)(data & 0x0F);

                            decodedData[width * ((yBlock * 8) + pY) + (xBlock * 8) + pX + 0] = (byte)(t >> 4);
                            decodedData[width * ((yBlock * 8) + pY) + (xBlock * 8) + pX + 1] = t2;
                        }
                    }
                }
            }

            //Now look them up in the palette and turn them into actual colors.
            byte[] finalDest = new byte[decodedData.Length / 2];

            int pixelSize  = paletteFormat == PaletteFormats.IA8 ? 2 : 4;
            int destOffset = 0;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    UnpackPixelFromPalette(decodedData[y * width + x], ref finalDest, destOffset, imagePalette.GetBytes(), paletteFormat);
                    destOffset += pixelSize;
                }
            }

            return(finalDest);
        }
Beispiel #14
0
        private static byte[] DecodeData(byte[] data, uint width, uint height, TextureFormats format, Palette imagePalette, PaletteFormats paletteFormat)
        {
            switch (format)
            {
            case TextureFormats.C4:
                return(DecodeC4(new FileReader(data), width, height, imagePalette, paletteFormat));

            case TextureFormats.C8:
                return(DecodeC8(new FileReader(data), width, height, imagePalette, paletteFormat));

            default:
                return(DecodeData(data, width, height, format));
            }
        }
Beispiel #15
0
 private static byte[] DecodeData(EndianBinaryReader stream, uint width, uint height, TextureFormats format, Palette imagePalette, PaletteFormats paletteFormat)
 {
     switch (format)
     {
         case TextureFormats.I4:
             return DecodeI4(stream, width, height);
         case TextureFormats.I8:
             return DecodeI8(stream, width, height);
         case TextureFormats.IA4:
             return DecodeIA4(stream, width, height);
         case TextureFormats.IA8:
             return DecodeIA8(stream, width, height);
         case TextureFormats.RGB565:
             return DecodeRgb565(stream, width, height);
         case TextureFormats.RGB5A3:
             return DecodeRgb5A3(stream, width, height);
         case TextureFormats.RGBA32:
             return DecodeRgba32(stream, width, height);
         case TextureFormats.C4:
             return DecodeC4(stream, width, height, imagePalette, paletteFormat);
         case TextureFormats.C8:
             return DecodeC8(stream, width, height, imagePalette, paletteFormat);
         case TextureFormats.CMPR:
             return DecodeCmpr(stream, width, height);
         case TextureFormats.C14X2:
         default:
             WLog.Warning(LogCategory.Textures, null, "Unsupported Binary Texture Image format {0}, unable to decode!", format);
             return new byte[0];
     }
 }
Beispiel #16
0
 public static System.Drawing.Bitmap DecodeDataToBitmap(byte[] ImageData, ushort[] PaletteData, uint width, uint height, TextureFormats format, PaletteFormats palleteFormat)
 {
     return(BitmapExtension.GetBitmap(DecodeData(ImageData, PaletteData, width, height, format, palleteFormat),
                                      (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb));
 }
Beispiel #17
0
 private static void UnpackPixelFromPalette(int paletteIndex, ref byte[] dest, int offset, byte[] paletteData, PaletteFormats format)
 {
     switch (format)
     {
         case PaletteFormats.IA8:
             dest[0] = paletteData[2 * paletteIndex + 1];
             dest[1] = paletteData[2 * paletteIndex + 0];
             break;
         case PaletteFormats.RGB565:
             {
                 ushort palettePixelData = (ushort)((Buffer.GetByte(paletteData, 2 * paletteIndex) << 8) | Buffer.GetByte(paletteData, 2 * paletteIndex + 1));
                 RGB565ToRGBA8(palettePixelData, ref dest, offset);
             }
             break;
         case PaletteFormats.RGB5A3:
             {
                 ushort palettePixelData = (ushort)((Buffer.GetByte(paletteData, 2 * paletteIndex) << 8) | Buffer.GetByte(paletteData, 2 * paletteIndex + 1));
                 RGB5A3ToRGBA8(palettePixelData, ref dest, offset);
             }
             break;
     }
 }
Beispiel #18
0
        public static Tuple <List <byte[]>, ushort[]> GenerateMipList(byte[] uncompressedData, uint TexWidth, uint TexHeight,
                                                                      uint MipCount, TextureFormats Format, PaletteFormats PaletteFormat)
        {
            Bitmap Image = BitmapExtension.CreateBitmap(uncompressedData, (int)TexWidth, (int)TexHeight);

            return(GenerateMipList(Image, TexWidth, TexHeight, MipCount, Format, PaletteFormat));
        }