public static byte[] RAWWriter(Image img, TxtrFormats format) { if (img == null) { return(new byte[0]); } System.IO.BinaryWriter writer = new System.IO.BinaryWriter(new System.IO.MemoryStream()); Bitmap bmp = (Bitmap)img; for (int y = 0; y < bmp.Height; y++) { for (int x = 0; x < bmp.Width; x++) { Color c = bmp.GetPixel(x, y); writer.Write((byte)c.B); if ((format != TxtrFormats.Raw8Bit) && (format != TxtrFormats.ExtRaw8Bit)) { writer.Write((byte)c.G); writer.Write((byte)c.R); if ((format == TxtrFormats.Raw32Bit)) { writer.Write((byte)c.A); } } } } System.IO.BinaryReader reader = new System.IO.BinaryReader(writer.BaseStream); reader.BaseStream.Seek(0, System.IO.SeekOrigin.Begin); return(reader.ReadBytes((int)reader.BaseStream.Length)); }
public static Image RAWParser(Size parentsize, TxtrFormats format, int imgsize, System.IO.BinaryReader reader, int w, int h) { double scale = ((double)parentsize.Width / (double)parentsize.Height); /*int w = 0; * int h = 0; * if ( (format == TxtrFormats.Raw24Bit) || (format == TxtrFormats.ExtRaw24Bit)) * { * h = Convert.ToInt32(Math.Sqrt((imgsize/3) / scale)); * w = Convert.ToInt32(h * scale); * } * else if ( format == TxtrFormats.Raw32Bit) * { * h = Convert.ToInt32(Math.Sqrt((imgsize/4) / scale)); * w = Convert.ToInt32(h * scale); * } * else * { * h = Convert.ToInt32(Math.Sqrt((imgsize) / scale)); * w = Convert.ToInt32(h * scale); * } * if ((w==0) || (h==0)) return new Bitmap(1, 1);*/ w = Math.Max(1, w); h = Math.Max(1, h); Bitmap bmp = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb); for (int y = 0; y < bmp.Height; y++) { for (int x = 0; x < bmp.Width; x++) { byte a = 0xff; byte r = 0; byte g = 0; byte b = 0; b = reader.ReadByte(); if ((format != TxtrFormats.Raw8Bit) && (format != TxtrFormats.ExtRaw8Bit)) { g = reader.ReadByte(); r = reader.ReadByte(); if ((format == TxtrFormats.Raw32Bit)) { a = reader.ReadByte(); } bmp.SetPixel(x, y, Color.FromArgb(a, r, g, b)); } else { bmp.SetPixel(x, y, Color.FromArgb(a, b, b, b)); } } } return(bmp); }
/// <summary> /// Tries to load an Image from the datasource /// </summary> /// <param name="imgDimension">Maximum Dimensions of the Image (used to determin the aspect ration</param> /// <param name="datasize">Number of bytes used for the image in the Stream</param> /// <param name="format">FOrmat of the Image</param> /// <param name="reader">A Binary Reader. Position must be the start of the Image Data</param> /// <param name="level">The index of the Texture in the current MipMap use -1 if you don't want to specify an Level</param> /// <param name="levelcount">Number of Levels stored in the MipMap</param> /// <returns>null or a valid Image</returns> public static Image Load(Size imgDimension, int datasize, TxtrFormats format, System.IO.BinaryReader reader, int level, int levelcount) { Image img = null; int wd = imgDimension.Width; int hg = imgDimension.Height; if (level != -1) { int revlevel = Math.Max(0, levelcount - (level + 1)); for (int i = 0; i < revlevel; i++) { wd /= 2; hg /= 2; } } wd = Math.Max(1, wd); hg = Math.Max(1, hg); if (format == ImageLoader.TxtrFormats.DXT1Format) { datasize = (wd * hg) / 2; } else if (format == ImageLoader.TxtrFormats.Raw24Bit) { datasize = (wd * hg) * 3; } else if (format == ImageLoader.TxtrFormats.Raw32Bit) { datasize = (wd * hg) * 4; } else { datasize = (wd * hg); } if ((format == ImageLoader.TxtrFormats.DXT1Format) || (format == ImageLoader.TxtrFormats.DXT3Format) || (format == ImageLoader.TxtrFormats.DXT5Format)) { img = ImageLoader.DXT3Parser(imgDimension, format, datasize, reader, wd, hg); } else if ((format == ImageLoader.TxtrFormats.ExtRaw8Bit) || (format == ImageLoader.TxtrFormats.Raw8Bit) || (format == ImageLoader.TxtrFormats.Raw24Bit) || (format == ImageLoader.TxtrFormats.Raw32Bit) || (format == ImageLoader.TxtrFormats.ExtRaw24Bit)) { img = ImageLoader.RAWParser(imgDimension, format, datasize, reader, wd, hg); } return(img); }
/// <summary> /// Creates a Byte array for the passed Image /// </summary> /// <param name="format">The Format you want to store the Image in</param> /// <param name="img">The Image</param> /// <returns>A Byte array containing the Image Data</returns> public static byte[] Save(TxtrFormats format, Image img) { byte[] data = new byte[0]; if (img != null) { if ((format == ImageLoader.TxtrFormats.DXT1Format) || (format == ImageLoader.TxtrFormats.DXT3Format) || (format == ImageLoader.TxtrFormats.DXT5Format)) { data = ImageLoader.DXT3Writer(img, format); } else if ((format == ImageLoader.TxtrFormats.ExtRaw8Bit) || (format == ImageLoader.TxtrFormats.Raw8Bit) || (format == ImageLoader.TxtrFormats.Raw24Bit) || (format == ImageLoader.TxtrFormats.Raw32Bit) || (format == ImageLoader.TxtrFormats.ExtRaw24Bit)) { data = ImageLoader.RAWWriter(img, format); } } return(data); }
public static byte[] DXT3Writer(Image img, TxtrFormats format) { if (img == null) { return(new byte[0]); } System.IO.BinaryWriter writer = new System.IO.BinaryWriter(new System.IO.MemoryStream()); Bitmap bmp = (Bitmap)img; int[] imageSourceAlpha = new int[bmp.Width * bmp.Height]; for (int y = 0; y < bmp.Height; y += 4) // DXT encodes 4x4 blocks of pixels { for (int x = 0; x < bmp.Width; x += 4) { // decode the alpha data if (format == TxtrFormats.DXT3Format) // DXT3 has 64 bits of alpha data, then 64 bits of DXT1 RGB data { // DXT3 Alpha // 16 alpha values are here, one for each pixel, each is 4 bits long Color[] alphas = new Color[4]; for (int by = 0; by < 4; ++by) { for (int bx = 0; bx < 4; ++bx) { if ((x + bx < bmp.Width) && (y + by < bmp.Height)) { alphas[bx] = bmp.GetPixel(x + bx, y + by); } else { alphas[bx] = Color.Black; } } DXT3WriteTransparencyBlock(writer, alphas); } } else if (format == TxtrFormats.DXT5Format) { Color[] alphas = new Color[16]; for (int by = 0; by < 4; ++by) { for (int bx = 0; bx < 4; ++bx) { if ((x + bx < bmp.Width) && (y + by < bmp.Height)) { alphas[by * 4 + bx] = bmp.GetPixel(x + bx, y + by); } else { alphas[by * 4 + bx] = Color.Black; } } } DXT5WriteTransparencyBlock(writer, alphas); } Color[,] colors = new Color[4, 4]; for (int by = 0; by < 4; ++by) { for (int bx = 0; bx < 4; ++bx) { try { if ((x + bx < bmp.Width) && (y + by < bmp.Height)) { colors[bx, by] = bmp.GetPixel(x + bx, y + by); } else { colors[bx, by] = Color.Black; } } catch (Exception ex) { Helper.ExceptionMessage("", ex); } } } DXT3WriteTexel(writer, colors, format); } // for x } // for y System.IO.BinaryReader reader = new System.IO.BinaryReader(writer.BaseStream); reader.BaseStream.Seek(0, System.IO.SeekOrigin.Begin); return(reader.ReadBytes((int)reader.BaseStream.Length)); }
protected static void DXT3WriteTexel(System.IO.BinaryWriter writer, Color[,] colors, TxtrFormats format) { Color[] table = new Color[4]; table[0] = Color.White; table[1] = Color.Black; //find extreme Colors for (byte y = 0; y < 4; y++) { for (byte x = 0; x < 4; x++) { Color dum = colors[x, y]; DXT3MinColor(ref table[0], dum); DXT3MaxColor(ref table[1], dum); } } //invert the Color Order //if ((format==TxtrFormats.DXT1Format) && (table[0].ToArgb()<=table[1].ToArgb()) ) if ((table[0].ToArgb() <= table[1].ToArgb())) { table[2] = DXT3MixColors(table[0], table[1], 1.0 / 2, 1.0 / 2); table[3] = Color.Black; } else { //build color table table[2] = DXT3MixColors(table[0], table[1], 2.0 / 3, 1.0 / 3); table[3] = DXT3MixColors(table[0], table[1], 1.0 / 3, 2.0 / 3); } writer.Write(DXT3Get565Color(table[0])); writer.Write(DXT3Get565Color(table[1])); //write Colors for (short y = 0; y < 4; y++) { int dum = 0; for (short x = 3; x >= 0; x--) { dum = dum << 2; dum = dum | (DXT3NearestTableColor(table, colors[x, y])); } writer.Write((byte)dum); } }
// // DXT1 RGB, DXT3, DXT5 Parser // DXT1 RGBA ist nicht behandelt weil nicht bekannt ist welchen Wert // format hat. Code ist auskommentiert! // public static Image DXT3Parser(Size parentsize, TxtrFormats format, int imgsize, System.IO.BinaryReader reader, int wd, int hg) { Bitmap bm = null; try { double ration = ((double)parentsize.Width) / ((double)parentsize.Height); if ((format == TxtrFormats.DXT3Format) || (format == TxtrFormats.DXT5Format) /* || (format == DXT1 RGBA) */) { //hg = Convert.ToInt32(Math.Sqrt(((double) imgsize) / ration)); //wd = Convert.ToInt32((double) (hg * ration)); if ((wd == 0) || (hg == 0)) { return(new Bitmap(Math.Max(1, wd), Math.Max(1, hg))); } bm = new Bitmap(wd, hg, System.Drawing.Imaging.PixelFormat.Format32bppArgb); } else { //hg = Convert.ToInt32(Math.Sqrt(((double) (2 * imgsize)) / ration)); //wd = Convert.ToInt32((double) (hg * ration)); if ((wd == 0) || (hg == 0)) { return(new Bitmap(Math.Max(1, wd), Math.Max(1, hg))); } bm = new Bitmap(wd, hg, System.Drawing.Imaging.PixelFormat.Format24bppRgb); } // int[] Alpha = new int[16]; // FH: für Alpha reicht hier [4 * 4] !!!! for (int y = 0; y < bm.Height; y += 4) // DXT encodes 4x4 blocks of pixel { for (int x = 0; x < bm.Width; x += 4) { // decode the alpha data (DXT3) if (format == TxtrFormats.DXT3Format) { long abits = reader.ReadInt64(); // 16 alpha values are here, one for each pixel, each 4 bits long for (int i = 0; i < 16; i++) { Alpha[i] = (int)((abits & 0xf) * 0x11); // je 4 bit herausschieben abits >>= 4; } // for by } else if (format == TxtrFormats.DXT5Format) // DXT5 { int alpha1 = reader.ReadByte(); int alpha2 = reader.ReadByte(); long abits = (long)reader.ReadUInt32() | ((long)reader.ReadUInt16() << 32); int[] alphas = new int[8]; // holds the calculated alpha values alphas[0] = alpha1; alphas[1] = alpha2; if (alpha1 > alpha2) { alphas[2] = (6 * alpha1 + alpha2) / 7; alphas[3] = (5 * alpha1 + 2 * alpha2) / 7; alphas[4] = (4 * alpha1 + 3 * alpha2) / 7; alphas[5] = (3 * alpha1 + 4 * alpha2) / 7; alphas[6] = (2 * alpha1 + 5 * alpha2) / 7; alphas[7] = (alpha1 + 6 * alpha2) / 7; } else { alphas[2] = (4 * alpha1 + alpha2) / 5; alphas[3] = (3 * alpha1 + 2 * alpha2) / 5; alphas[4] = (2 * alpha1 + 3 * alpha2) / 5; alphas[5] = (1 * alpha1 + 4 * alpha2) / 5; alphas[6] = 0; alphas[7] = 0xff; } for (int i = 0; i < 16; i++) { Alpha[i] = alphas[abits & 7]; // je 3 bit als Code herausschieben abits >>= 3; } } // if format.. // decode the DXT1 RGB data // two 16 bit encoded colors (red 5, green 6, blue 5 bits) int c1packed16 = reader.ReadUInt16(); int c2packed16 = reader.ReadUInt16(); // separate R,G,B int color1r = Convert.ToByte(((c1packed16 >> 11) & 0x1F) * 8.2258064516129032258064516129032); int color1g = Convert.ToByte(((c1packed16 >> 5) & 0x3F) * 4.047619047619047619047619047619); int color1b = Convert.ToByte((c1packed16 & 0x1F) * 8.2258064516129032258064516129032); int color2r = Convert.ToByte(((c2packed16 >> 11) & 0x1F) * 8.2258064516129032258064516129032); int color2g = Convert.ToByte(((c2packed16 >> 5) & 0x3F) * 4.047619047619047619047619047619); int color2b = Convert.ToByte((c2packed16 & 0x1F) * 8.2258064516129032258064516129032); // FH: colors definieren wir gleich als Color Color[] colors = new Color[4]; // colors 0 and 1 point to the two 16 bit colors we read in colors[0] = Color.FromArgb(color1r, color1g, color1b); colors[1] = Color.FromArgb(color2r, color2g, color2b); // FH: DXT1 RGB? Reihenfolge wichtig! /*if ((format == TxtrFormats.DXT1Format) && (c1packed16 <= c2packed16)) * { * // 1/2 color 1, 1/2 color2 * colors[2] = Color.FromArgb( * ((color1r + color2r) >> 1) & 0xff, * ((color1g + color2g) >> 1) & 0xff, * ((color1b + color2b) >> 1) & 0xff); * // BLACK * colors[3] = Color.Black; * } * else // Alle anderen*/ { // 2/3 color 1, 1/3 color2 colors[2] = Color.FromArgb( (((color1r << 1) + color2r) / 3) & 0xff, (((color1g << 1) + color2g) / 3) & 0xff, (((color1b << 1) + color2b) / 3) & 0xff); // 2/3 color2, 1/3 color1 colors[3] = Color.FromArgb( (((color2r << 1) + color1r) / 3) & 0xff, (((color2g << 1) + color1g) / 3) & 0xff, (((color2b << 1) + color1b) / 3) & 0xff); } // read in the color code bits, 16 values, each 2 bits long // then look up the color in the color table we built uint cbits = reader.ReadUInt32(); for (int by = 0; by < 4; by++) { for (int bx = 0; bx < 4; bx++) { try { if (((x + bx) < wd) && ((y + by) < hg)) { uint code = (cbits >> (((by << 2) + bx) << 1)) & 3; if ((format == TxtrFormats.DXT3Format) || (format == TxtrFormats.DXT5Format)) { bm.SetPixel(x + bx, y + by, Color.FromArgb(Alpha[(by << 2) + bx], colors[code])); } else { // if (format == DXT1_RGBA) // { // if ((c1packed16 <= c2packed16) && (code == 3)) // { // bm.SetPixel(x + bx, y + by, Color.FromArgb(0, colors[code]); // } else { // bm.SetPixel(x + bx, y + by, Color.FromArgb(255, colors[code]); // } // } else { bm.SetPixel(x + bx, y + by, colors[code]); // } } } } catch (Exception exception1) { Helper.ExceptionMessage("", exception1); } } } // for by } // for x } // for y } catch (Exception ex) { Helper.ExceptionMessage("", ex); } return(bm); }