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); } }
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; }
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; } }
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); }
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]); } }
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)); }
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)); }
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; } }
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)); }
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])); } }
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]); } }
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); }
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)); } }
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]; } }
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)); }
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; } }
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)); }