예제 #1
0
        public override void DrawArc(double x1, double y1, double x2, double y2, double bulge)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawArc(x1, y1, x2, y2, bulge);
                return;
            }

            stipplebit = 0x8000;

            int clipres = Clipper.ClipArc(x1, y1, x2, y2, bulge, clipbuffer, clipMinX, clipMinY, clipMaxX, clipMaxY);

            for (int idx = 0; idx < clipres; idx += 5)
            {
                int cx = GFXUtil.FloatToInt(clipbuffer[idx]), cy = GFXUtil.FloatToInt(clipbuffer[idx + 1]), nx, ny;
                GeomUtil.FlattenArc(clipbuffer[idx], clipbuffer[idx + 1], clipbuffer[idx + 2], clipbuffer[idx + 3], clipbuffer[idx + 4], false, flattentol, (x, y, moveto) =>
                {
                    nx = GFXUtil.FloatToInt(x);
                    ny = GFXUtil.FloatToInt(y);
                    Line_Internal(cx, cy, nx, ny, x2 == x && y2 == y); //set last point if last segment
                    cx = nx;
                    cy = ny;
                });
            }
        }
예제 #2
0
 private static Color[] ConvertXBGR1555(byte[] Data)
 {
     Color[] data = new Color[Data.Length / 2];
     for (int i = 0; i < Data.Length; i += 2)
     {
         data[i / 2] = Color.FromArgb((int)GFXUtil.XBGR1555ToArgb(IOUtil.ReadU16LE(Data, i)));
     }
     return(data);
 }
예제 #3
0
 private static Color[] ConvertABGR1555(byte[] Data)
 {
     Color[] data = new Color[Data.Length / 2];
     for (int i = 0; i < Data.Length; i += 2)
     {
         data[i / 2] = Color.FromArgb((int)GFXUtil.ConvertColorFormat(IOUtil.ReadU16LE(Data, i), ColorFormat.ABGR1555, ColorFormat.ARGB8888));
     }
     return(data);
 }
예제 #4
0
        public void MaterialColor1(uint cmd)
        {
            ushort spec  = (ushort)(cmd & 0x7FFF);
            bool   shine = (cmd & 0x8000) != 0;
            ushort emiss = (ushort)((cmd >> 16) & 0x7FFF);

            UsesSpecularReflectionTable = shine;
            SpecularColor = System.Drawing.Color.FromArgb((int)GFXUtil.XBGR1555ToArgb(spec));
            EmissionColor = System.Drawing.Color.FromArgb((int)GFXUtil.XBGR1555ToArgb(emiss));
        }
예제 #5
0
        public override void DrawLine(double x1, double y1, double x2, double y2)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawLine(x1, y1, x2, y2);
                return;
            }

            stipplebit = 0x8000;
            Line_Internal(GFXUtil.FloatToInt(x1), GFXUtil.FloatToInt(y1), GFXUtil.FloatToInt(x2), GFXUtil.FloatToInt(y2), true);
        }
 private void button3_Click(object sender, EventArgs e)
 {
     openFileDialog1.Title = "Import Small Icon";
     if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
         openFileDialog1.FileName.Length > 0)
     {
         Bitmap b = GFXUtil.Resize(new Bitmap(new MemoryStream(File.ReadAllBytes(openFileDialog1.FileName))), 24, 24);
         icn.SmallIcon = GPU.Textures.FromBitmap(b, GPU.Textures.ImageFormat.RGB565, true);
         b.Dispose();
         pictureBox1.Image = icn.GetSmallIcon();
     }
 }
예제 #7
0
        public void MaterialColor0(uint cmd)
        {
            ushort diff = (ushort)(cmd & 0x7FFF);
            bool   vtx  = (cmd & 0x8000) != 0;
            ushort amb  = (ushort)((cmd >> 16) & 0x7FFF);

            DiffuseColor = System.Drawing.Color.FromArgb((int)GFXUtil.XBGR1555ToArgb(diff));
            AmbientColor = System.Drawing.Color.FromArgb((int)GFXUtil.XBGR1555ToArgb(amb));
            if (vtx)
            {
                Color(DiffuseColor);
            }
        }
예제 #8
0
        public void MaterialColor0(uint cmd)
        {
            ushort diff = (ushort)(cmd & 0x7FFF);
            bool   vtx  = (cmd & 0x8000) != 0;
            ushort amb  = (ushort)((cmd >> 16) & 0x7FFF);

            DiffuseColor = System.Drawing.Color.FromArgb((int)GFXUtil.ConvertColorFormat(diff, ColorFormat.XBGR1555, ColorFormat.ARGB8888));
            AmbientColor = System.Drawing.Color.FromArgb((int)GFXUtil.ConvertColorFormat(amb, ColorFormat.XBGR1555, ColorFormat.ARGB8888));
            if (vtx)
            {
                Color(DiffuseColor);
            }
        }
예제 #9
0
        public static ushort StringColorToXBGR(string c)
        {
            var rgbVals = new[]
            {
                byte.Parse(c.Split(' ')[0]) * 8,
                byte.Parse(c.Split(' ')[1]) * 8,
                byte.Parse(c.Split(' ')[2]) * 8
            };

            var color = (ushort)GFXUtil.ConvertColorFormat((uint)Color.FromArgb(rgbVals[0], rgbVals[1], rgbVals[2]).ToArgb(),
                                                           ColorFormat.ARGB8888, ColorFormat.ABGR1555);

            return(color);
        }
예제 #10
0
        public override void DrawEllipticArc(double cx, double cy, double aradius, double bradius, double tilt, double startangle, double sweepangle)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawEllipticArc(cx, cy, aradius, bradius, tilt, startangle, sweepangle);
                return;
            }

            /* stipplebit = 0x8000;
             *
             * int px=0,py=0,nx,ny;
             * bool first = true;
             *
             * GeomUtil.FlattenEllipticArc(cx, cy, aradius, bradius, tilt, startangle, sweepangle, flattentol, true, (x, y,moveto) =>
             * {
             *   nx = GFXUtil.RealToInt(x);
             *   ny = GFXUtil.RealToInt(y);
             *   if (!first)
             *       Line_Internal(px, py, nx, ny, true); //TODO: can we skip last pixel except on last segment?
             *   else
             *       first = false;
             *
             *
             *   px = nx;
             *   py = ny;
             * });*/


            int px = 0, py = 0, nx, ny;

            int num = Clipper.ClipEllipticArc(cx, cy, aradius, bradius, tilt, startangle, sweepangle, clipbuffer, clipMinX, clipMinY, clipMaxX, clipMaxY);

            for (int l = 0; l < num; l += 2)
            {
                stipplebit = 0x8000;

                GeomUtil.FlattenEllipticArc(cx, cy, aradius, bradius, tilt, clipbuffer[l], clipbuffer[l + 1] - clipbuffer[l], flattentol, true, (x, y, moveto) =>
                {
                    nx = GFXUtil.FloatToInt(x);
                    ny = GFXUtil.FloatToInt(y);
                    if (!moveto)
                    {
                        Line_Internal(px, py, nx, ny, true); //TODO: can we skip last pixel except on last segment?
                    }
                    px = nx;
                    py = ny;
                });
            }
        }
예제 #11
0
        public override void DrawRectangleT(double x1, double y1, double x2, double y2)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawRectangleT(x1, y1, x2, y2);
                return;
            }

            stipplebit = 0x8000;

            //convert to four points as poly to be able to transform
            double x3 = x2;
            double y3 = y2;

            y2 = y1;
            double x4 = x1;
            double y4 = y3;

            Transform.Apply(x1, y1, out x1, out y1, true);
            Transform.Apply(x2, y2, out x2, out y2, true);
            Transform.Apply(x3, y3, out x3, out y3, true);
            Transform.Apply(x4, y4, out x4, out y4, true);

            int ix1 = GFXUtil.FloatToInt(x1);
            int iy1 = GFXUtil.FloatToInt(y1);
            int ix2 = GFXUtil.FloatToInt(x2);
            int iy2 = GFXUtil.FloatToInt(y2);
            int ix3 = GFXUtil.FloatToInt(x3);
            int iy3 = GFXUtil.FloatToInt(y3);
            int ix4 = GFXUtil.FloatToInt(x4);
            int iy4 = GFXUtil.FloatToInt(y4);

            //check for pixel sized rectangle
            if (ix1 == ix2 && ix2 == ix3 && ix3 == ix4 && iy1 == iy2 && iy2 == iy3 && iy3 == iy4)
            {
                SetPixel(ix1, iy1, color);
                return;
            }

            Line_Internal(ix1, iy1, ix2, iy2, false);
            Line_Internal(ix2, iy2, ix3, iy3, false);
            Line_Internal(ix3, iy3, ix4, iy4, false);
            Line_Internal(ix4, iy4, ix1, iy1, false);
        }
예제 #12
0
 public void Write(EndianBinaryWriter er)
 {
     er.Write(Signature, Encoding.ASCII, false);
     er.Write(Unknown1);
     er.Write(NrLaps);
     er.Write(Unknown2);
     er.Write((Byte)(FogEnabled ? 1 : 0));
     er.Write(FogTableGenMode);
     er.Write(FogSlope);
     er.Write(UnknownData1, 0, 8);
     er.WriteFx32(FogDensity);
     er.Write((UInt16)(GFXUtil.ConvertColorFormat((uint)FogColor.ToArgb(), ColorFormat.ARGB8888, ColorFormat.XBGR1555) | 0x8000));
     er.Write(FogAlpha);
     er.Write((UInt16)GFXUtil.ConvertColorFormat((uint)KclColor1.ToArgb(), ColorFormat.ARGB8888, ColorFormat.XBGR1555));
     er.Write((UInt16)GFXUtil.ConvertColorFormat((uint)KclColor2.ToArgb(), ColorFormat.ARGB8888, ColorFormat.XBGR1555));
     er.Write((UInt16)GFXUtil.ConvertColorFormat((uint)KclColor3.ToArgb(), ColorFormat.ARGB8888, ColorFormat.XBGR1555));
     er.Write((UInt16)GFXUtil.ConvertColorFormat((uint)KclColor4.ToArgb(), ColorFormat.ARGB8888, ColorFormat.XBGR1555));
     er.WriteFx32(FrustumFar);
     er.Write(UnknownData2, 0, 4);
 }
예제 #13
0
        public override void DrawPolyLine(bool close, params double[] xy)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawPolyLine(close, xy);
                return;
            }

            stipplebit = 0x8000;

            int n = xy.Length;

            if (xy.Length < 2)
            {
                return;
            }

            int prevx  = GFXUtil.FloatToInt(xy[0]);
            int prevy  = GFXUtil.FloatToInt(xy[1]);
            int firstx = prevx;
            int firsty = prevy;

            int lastidx = n - 2;

            for (int l = 0; l < n;)
            {
                bool lastpixel = l == lastidx;

                int nextx = GFXUtil.FloatToInt(xy[l++]);
                int nexty = GFXUtil.FloatToInt(xy[l++]);

                Line_Internal(prevx, prevy, nextx, nexty, lastpixel);
                prevx = nextx;
                prevy = nexty;
            }

            if (close)
            {
                Line_Internal(prevx, prevy, firstx, firsty, false);
            }
        }
        private void MDL0MaterialEditor_Load(object sender, EventArgs e)
        {
            checkBox3.Checked       = (Material.polyAttr & 1) != 0;
            checkBox4.Checked       = (Material.polyAttr & 2) != 0;
            checkBox5.Checked       = (Material.polyAttr & 4) != 0;
            checkBox6.Checked       = (Material.polyAttr & 8) != 0;
            comboBox1.SelectedIndex = (int)((Material.polyAttr >> 4) & 0x3);
            comboBox2.SelectedIndex = (int)((Material.polyAttr >> 6) & 0x3);
            checkBox7.Checked       = ((Material.polyAttr >> 11) & 0x1) == 1;
            checkBox8.Checked       = ((Material.polyAttr >> 12) & 0x1) == 1;
            checkBox9.Checked       = ((Material.polyAttr >> 13) & 0x1) == 1;
            comboBox3.SelectedIndex = (int)((Material.polyAttr >> 14) & 0x1);
            checkBox10.Checked      = ((Material.polyAttr >> 15) & 0x1) == 1;
            trackBar1.Value         = (int)((Material.polyAttr >> 16) & 31);
            trackBar2.Value         = (int)((Material.polyAttr >> 24) & 63);

            checkBox1.Checked = (Material.diffAmb & 0x8000) != 0;
            button1.BackColor = Color.FromArgb((int)GFXUtil.ConvertColorFormat(Material.diffAmb & 0x7FFF, ColorFormat.XBGR1555, ColorFormat.ARGB8888));            //(int)GFXUtil.XBGR1555ToArgb((ushort)(Material.diffAmb & 0x7FFF)));
            button2.BackColor = Color.FromArgb((int)GFXUtil.ConvertColorFormat((Material.diffAmb >> 16) & 0x7FFF, ColorFormat.XBGR1555, ColorFormat.ARGB8888));

            checkBox2.Checked = (Material.specEmi & 0x8000) != 0;
            button3.BackColor = Color.FromArgb((int)GFXUtil.ConvertColorFormat(Material.specEmi & 0x7FFF, ColorFormat.XBGR1555, ColorFormat.ARGB8888));
            button4.BackColor = Color.FromArgb((int)GFXUtil.ConvertColorFormat((Material.specEmi >> 16) & 0x7FFF, ColorFormat.XBGR1555, ColorFormat.ARGB8888));

            uint wrapS = (Material.texImageParam >> 16) & 1;

            if (wrapS != 0)
            {
                wrapS += (Material.texImageParam >> 18) & 1;
            }
            comboBox4.SelectedIndex = (int)wrapS;
            uint wrapT = (Material.texImageParam >> 17) & 1;

            if (wrapT != 0)
            {
                wrapT += (Material.texImageParam >> 19) & 1;
            }
            comboBox5.SelectedIndex = (int)wrapT;
        }
예제 #15
0
        private void InternalDrawBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
        {
            int n = Clipper.ClipBezier(x1, y1, x2, y2, x3, y3, x4, y4, clipbuffer, clipMinX, clipMinY, clipMaxX, clipMaxY);
            int penx = 0, peny = 0;

            for (int l = 0; l < n; l += 2)
            {
                GeomUtil.FlattenBezier(x1, y1, x2, y2, x3, y3, x4, y4, true, flattentol, (x, y, moveto) =>
                {
                    int nextx = GFXUtil.FloatToInt(x);
                    int nexty = GFXUtil.FloatToInt(y);

                    if (!moveto)
                    {
                        Line_Internal(penx, peny, nextx, nexty, false);
                    }

                    penx = nextx;
                    peny = nexty;
                }, clipbuffer[l], clipbuffer[l + 1]);
            }
        }
예제 #16
0
        public override void DrawRectangle(double x1, double y1, double x2, double y2)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawRectangle(x1, y1, x2, y2);
                return;
            }

            stipplebit = 0x8000;

            int ix1 = GFXUtil.FloatToInt(x1);
            int iy1 = GFXUtil.FloatToInt(y1);
            int ix2 = GFXUtil.FloatToInt(x2);
            int iy2 = GFXUtil.FloatToInt(y2);

            if (ix1 == ix2)
            {
                if (iy1 == iy2)
                {
                    SetPixel(ix1, iy1, color);
                    return;
                }
                else
                {
                    Line_Internal(ix1, iy1, ix1, iy2, true); //vertical line
                    return;
                }
            }
            else if (iy1 == iy2)
            {
                Line_Internal(ix1, iy1, ix2, iy1, true); //horizontal line
                return;
            }

            Line_Internal(ix1, iy1, ix2, iy1, false);
            Line_Internal(ix2, iy1, ix2, iy2, false);
            Line_Internal(ix2, iy2, ix1, iy2, false);
            Line_Internal(ix1, iy2, ix1, iy1, false);
        }
예제 #17
0
                public unsafe Bitmap ToBitmap(bool swap = false, bool alpha = false)
                {
                    int width  = (int)DecompressedSize / 32 / 2;
                    int height = 32;

                    if (swap)
                    {
                        height = width;
                        width  = 32;
                    }
                    Bitmap     b      = new Bitmap(width, height);
                    BitmapData d      = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                    uint *     result = (uint *)d.Scan0;
                    int        stride = d.Stride / 4;
                    int        offs   = 0;

                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++)
                        {
                            if (!alpha)
                            {
                                result[y * stride + x] = GFXUtil.ConvertColorFormat(
                                    IOUtil.ReadU16BE(TexData, offs),
                                    ColorFormat.RGBA5551,
                                    ColorFormat.ARGB8888);
                            }
                            else
                            {
                                byte c = TexData[offs];
                                byte a = TexData[offs + 1];
                                result[y * stride + x] = GFXUtil.ToColorFormat(a, c, c, c, ColorFormat.ARGB8888);
                            }
                            offs += 2;
                        }
                    }
                    b.UnlockBits(d);
                    return(b);
                }
예제 #18
0
 public STAG(EndianBinaryReader er)
 {
     Signature = er.ReadString(Encoding.ASCII, 4);
     if (Signature != "STAG")
     {
         throw new SignatureNotCorrectException(Signature, "STAG", er.BaseStream.Position - 4);
     }
     Unknown1        = er.ReadUInt16();
     NrLaps          = er.ReadInt16();
     Unknown2        = er.ReadByte();
     FogEnabled      = er.ReadByte() == 1;
     FogTableGenMode = er.ReadByte();
     FogSlope        = er.ReadByte();
     UnknownData1    = er.ReadBytes(0x8);
     FogDensity      = er.ReadFx32();
     FogColor        = Color.FromArgb((int)GFXUtil.XBGR1555ToArgb(er.ReadUInt16()));
     FogAlpha        = er.ReadUInt16();
     KclColor1       = Color.FromArgb((int)GFXUtil.XBGR1555ToArgb(er.ReadUInt16()));
     KclColor2       = Color.FromArgb((int)GFXUtil.XBGR1555ToArgb(er.ReadUInt16()));
     KclColor3       = Color.FromArgb((int)GFXUtil.XBGR1555ToArgb(er.ReadUInt16()));
     KclColor4       = Color.FromArgb((int)GFXUtil.XBGR1555ToArgb(er.ReadUInt16()));
     UnknownData2    = er.ReadBytes(0x8);
 }
예제 #19
0
        public static unsafe byte[] FromBitmap(Bitmap Picture, ImageFormat Format, bool ExactSize = false)
        {
            if (ExactSize && ((Picture.Width % 8) != 0 || (Picture.Height % 8) != 0))
            {
                return(null);
            }
            int physicalwidth  = Picture.Width;
            int physicalheight = Picture.Height;
            int ConvWidth      = Picture.Width;
            int ConvHeight     = Picture.Height;

            if (!ExactSize)
            {
                ConvWidth  = 1 << (int)Math.Ceiling(Math.Log(Picture.Width, 2));
                ConvHeight = 1 << (int)Math.Ceiling(Math.Log(Picture.Height, 2));
            }
            BitmapData d   = Picture.LockBits(new Rectangle(0, 0, Picture.Width, Picture.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            uint *     res = (uint *)d.Scan0;

            byte[] result = new byte[ConvWidth * ConvHeight * GetBpp(Format) / 8];
            int    offs   = 0;

            switch (Format)
            {
            case ImageFormat.RGBA8:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int   pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            Color c   = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);
                            result[offs + pos * 4 + 0] = c.A;
                            result[offs + pos * 4 + 1] = c.B;
                            result[offs + pos * 4 + 2] = c.G;
                            result[offs + pos * 4 + 3] = c.R;
                        }
                        offs += 64 * 4;
                    }
                }
                break;

            case ImageFormat.RGB8:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int   pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            Color c   = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);
                            result[offs + pos * 3 + 0] = c.B;
                            result[offs + pos * 3 + 1] = c.G;
                            result[offs + pos * 3 + 2] = c.R;
                        }
                        offs += 64 * 3;
                    }
                }
                break;

            case ImageFormat.RGBA5551:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvHeight; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            IOUtil.WriteU16LE(result, offs + pos * 2, (ushort)GFXUtil.ConvertColorFormat(res[(y + y2) * d.Stride / 4 + x + x2], ColorFormat.ARGB8888, ColorFormat.RGBA5551));
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case ImageFormat.RGB565:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            IOUtil.WriteU16LE(result, offs + pos * 2, (ushort)GFXUtil.ConvertColorFormat(res[(y + y2) * d.Stride / 4 + x + x2], ColorFormat.ARGB8888, ColorFormat.RGB565));     //GFXUtil.ArgbToRGB565(res[(y + y2) * d.Stride / 4 + x + x2]));
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case ImageFormat.RGBA4:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            IOUtil.WriteU16LE(result, offs + pos * 2, (ushort)GFXUtil.ConvertColorFormat(res[(y + y2) * d.Stride / 4 + x + x2], ColorFormat.ARGB8888, ColorFormat.RGBA4444));
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case ImageFormat.LA8:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int   pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            Color c   = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);
                            result[offs + pos * 2]     = c.A;
                            result[offs + pos * 2 + 1] = c.B;
                            result[offs + pos * 2 + 1] = c.G;
                            result[offs + pos * 2 + 1] = c.R;
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            //case ImageFormat.HILO8:
            //    for (int y = 0; y < ConvHeight; y += 8)
            //    {
            //        for (int x = 0; x < ConvWidth; x += 8)
            //        {
            //            for (int i = 0; i < 64; i++)
            //            {
            //                int x2 = i % 8;
            //                if (x + x2 >= physicalwidth) continue;
            //                int y2 = i / 8;
            //                if (y + y2 >= physicalheight) continue;
            //                int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
            //                Color c = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);
            //                result[offs + pos * 2] = c.A;
            //                result[offs + pos * 2 + 1] = c.B;
            //                result[offs + pos * 2 + 1] = c.G;
            //                result[offs + pos * 2 + 1] = c.R;
            //            }
            //            offs += 64 * 2;
            //        }
            //    }
            //    break;
            //case ImageFormat.L8:
            //    for (int y = 0; y < ConvHeight; y += 8)
            //    {
            //        for (int x = 0; x < ConvWidth; x += 8)
            //        {
            //            for (int i = 0; i < 64; i++)
            //            {
            //                int x2 = i % 8;
            //                if (x + x2 >= physicalwidth) continue;
            //                int y2 = i / 8;
            //                if (y + y2 >= physicalheight) continue;
            //                int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
            //                Color c = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);
            //                result[offs + pos] = c.B;
            //                result[offs + pos] = c.G;
            //                result[offs + pos] = c.R;
            //            }
            //            offs += 64;
            //        }
            //    }
            //    break;
            //case ImageFormat.A8:
            //    for (int y = 0; y < ConvHeight; y += 8)
            //    {
            //        for (int x = 0; x < ConvWidth; x += 8)
            //        {
            //            for (int i = 0; i < 64; i++)
            //            {
            //                int x2 = i % 8;
            //                if (x + x2 >= physicalwidth) continue;
            //                int y2 = i / 8;
            //                if (y + y2 >= physicalheight) continue;
            //                int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
            //                Color c = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);
            //                result[offs + pos] = c.A;
            //            }
            //            offs += 64;
            //        }
            //    }
            //    break;
            //case ImageFormat.LA4:
            //    for (int y = 0; y < ConvHeight; y += 8)
            //    {
            //        for (int x = 0; x < ConvWidth; x += 8)
            //        {
            //            for (int i = 0; i < 64; i++)
            //            {
            //                int x2 = i % 8;
            //                if (x + x2 >= physicalwidth) continue;
            //                int y2 = i / 8;
            //                if (y + y2 >= physicalheight) continue;
            //                int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
            //                Color c = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);
            //            }
            //            offs += 64;
            //        }
            //    }
            //    break;
            //case ImageFormat.L4:
            //    for (int y = 0; y < ConvHeight; y += 8)
            //    {
            //        for (int x = 0; x < ConvWidth; x += 8)
            //        {
            //            for (int i = 0; i < 64; i++)
            //            {
            //                int x2 = i % 8;
            //                if (x + x2 >= physicalwidth) continue;
            //                int y2 = i / 8;
            //                if (y + y2 >= physicalheight) continue;
            //                int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
            //                Color c = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);
            //            }
            //            offs += 64 / 2;
            //        }
            //    }
            //    break;
            //case ImageFormat.A4:
            //    for (int y = 0; y < ConvHeight; y += 8)
            //    {
            //        for (int x = 0; x < ConvWidth; x += 8)
            //        {
            //            for (int i = 0; i < 64; i++)
            //            {
            //                int x2 = i % 8;
            //                if (x + x2 >= physicalwidth) continue;
            //                int y2 = i / 8;
            //                if (y + y2 >= physicalheight) continue;
            //                int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
            //                Color c = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);
            //            }
            //            offs += 64 / 2;
            //        }
            //    }
            //    break;
            case ImageFormat.ETC1:
            case ImageFormat.ETC1A4:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 8; i += 4)
                        {
                            for (int j = 0; j < 8; j += 4)
                            {
                                if (Format == ImageFormat.ETC1A4)
                                {
                                    ulong alpha = 0;
                                    int   iiii  = 0;
                                    for (int xx = 0; xx < 4; xx++)
                                    {
                                        for (int yy = 0; yy < 4; yy++)
                                        {
                                            uint color;
                                            if (x + j + xx >= physicalwidth)
                                            {
                                                color = 0x00FFFFFF;
                                            }
                                            else if (y + i + yy >= physicalheight)
                                            {
                                                color = 0x00FFFFFF;
                                            }
                                            else
                                            {
                                                color = res[((y + i + yy) * (d.Stride / 4)) + x + j + xx];
                                            }
                                            uint a = color >> 24;
                                            a    >>= 4;
                                            alpha |= (ulong)a << (iiii * 4);
                                            iiii++;
                                        }
                                    }
                                    IOUtil.WriteU64LE(result, offs, alpha);
                                    offs += 8;
                                }
                                Color[] pixels = new Color[4 * 4];
                                for (int yy = 0; yy < 4; yy++)
                                {
                                    for (int xx = 0; xx < 4; xx++)
                                    {
                                        if (x + j + xx >= physicalwidth)
                                        {
                                            pixels[yy * 4 + xx] = Color.Transparent;
                                        }
                                        else if (y + i + yy >= physicalheight)
                                        {
                                            pixels[yy * 4 + xx] = Color.Transparent;
                                        }
                                        else
                                        {
                                            pixels[yy * 4 + xx] = Color.FromArgb((int)res[((y + i + yy) * (d.Stride / 4)) + x + j + xx]);
                                        }
                                    }
                                }
                                IOUtil.WriteU64LE(result, offs, ETC1.GenETC1(pixels));
                                offs += 8;
                            }
                        }
                    }
                }
                break;

            default:
                throw new NotImplementedException("This format is not implemented yet.");
            }
            return(result);
        }
예제 #20
0
        /// <summary>
        /// Create a GDI+ Pen that corresponds to a Painter setup
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static Pen CreateLinePenFromPainter(Painter p)
        {
            Color c = PainterGDIPlus.RGBToColor(p.Color);

            if (p.Opacity < 0.999)
            {
                c = Color.FromArgb(GFXUtil.FloatToInt(MathUtil.Clamp(p.Opacity * 255.0, 0.0, 255.0)), c);
            }

            Pen linepen = new Pen(c, (float)Math.Abs(p.LineWidth)); //0 means the thinnest possible on device


            switch (p.LineStyle)
            {
            case LineStyle.Continuous: break;     //done already

            case LineStyle.Custom:
                SetCustomDashes(p.LineStyleDashes, p.LineWidth, linepen);
                linepen.DashStyle = DashStyle.Custom;
                break;

            case LineStyle.Dash:
                linepen.DashPattern = new float[] { 8, 8 };
                linepen.DashStyle   = DashStyle.Custom;
                break;

            case LineStyle.DashDotDot:
                linepen.DashPattern = new float[] { 7, 2, 2, 1, 2, 2 };
                linepen.DashStyle   = DashStyle.Custom;
                break;

            case LineStyle.DashDot:
                linepen.DashPattern = new float[] { 8, 3, 2, 3 };
                linepen.DashStyle   = DashStyle.Custom;
                break;

            case LineStyle.Dot:
                linepen.DashPattern = new float[] { 4, 4 };
                linepen.DashStyle   = DashStyle.Custom;
                break;
            }


            /*  if (p.LineStyle != LineStyle.Continuous)
             * {
             *    //linepen.DashStyle = LineStyleToDashStyle(p.LineStyle);
             *    linepen.DashStyle = DashStyle.Custom;
             *    if (p.LineStyle == LineStyle.Custom)
             *        SetCustomDashes(p.LineStyleDashes, linepen);
             *    else if (p.LineStyle == LineStyle.Dot)
             *        linepen.DashPattern = new float[] { 4, 4 };
             *    else
             *        linepen.DashPattern = new float[] { 10, 4, 4, 4 };
             *
             *
             *
             * }
             */

            LineCap ecap;
            DashCap dcap;

            if (p.EndCaps != EndCap.Flat) //flat is default for pen and thus need no change
            {
                GetEndCap(p.EndCaps, out ecap, out dcap);
                linepen.EndCap   = ecap;
                linepen.StartCap = ecap;
                linepen.DashCap  = dcap;
            }


            if (p.LineJoin != LineJoin.Miter)  //miter is default and thus needs no change
            {
                linepen.LineJoin = GetLineJoin(p.LineJoin);
            }

            return(linepen);
        }
예제 #21
0
        public static byte[] Encode(IEnumerable <DisplayListCommand> commands)
        {
            var m  = new MemoryStream();
            var ew = new EndianBinaryWriterEx(m, Endianness.LittleEndian);

            int offset = 0;
            int packed = 0;

            var cmdList = commands.ToList();

            var nops = (cmdList.Count % 4) == 0 ? 0 : 4 - (cmdList.Count % 4);

            //Add NOPs at the end
            for (int i = 0; i < nops; i++)
            {
                cmdList.Add(new DisplayListCommand(G3dCommand.Nop));
            }

            var commandQueue = new Queue <DisplayListCommand>();

            bool param0Flag = false;

            void Flush()
            {
                packed = 0;

                var count = commandQueue.Count;

                for (int i = 0; i < count; i++)
                {
                    var cmd = commandQueue.Dequeue();

                    //m.Position = offset;

                    switch (cmd.G3dCommand)
                    {
                    default:
                    case G3dCommand.Identity:
                    case G3dCommand.PushMatrix:
                    case G3dCommand.End:
                    case G3dCommand.Nop:
                        break;

                    case G3dCommand.TexCoord:
                        ew.WriteFixedPoint(cmd.RealArgs[0], true, 11, 4);
                        ew.WriteFixedPoint(cmd.RealArgs[1], true, 11, 4);
                        offset += 4;
                        break;

                    case G3dCommand.VertexXY:
                    case G3dCommand.VertexXZ:
                    case G3dCommand.VertexYZ:
                        ew.WriteFx16s(cmd.RealArgs);
                        offset += 4;
                        break;

                    case G3dCommand.Begin:
                    case G3dCommand.RestoreMatrix:
                        ew.Write(cmd.IntArgs[0]);
                        offset += 4;
                        break;

                    case G3dCommand.VertexDiff:
                        var vec2 = VecFx10.FromVector3((cmd.RealArgs[0] * 8, cmd.RealArgs[1] * 8,
                                                        cmd.RealArgs[2] * 8));
                        ew.Write(vec2);
                        offset += 4;
                        break;

                    case G3dCommand.VertexShort:
                        var vec3 = VecFx10.FromVector3((cmd.RealArgs[0], cmd.RealArgs[1], cmd.RealArgs[2]), 3,
                                                       6);
                        ew.Write(vec3);
                        offset += 4;
                        break;

                    case G3dCommand.Normal:
                        var vec = VecFx10.FromVector3((cmd.RealArgs[0], cmd.RealArgs[1], cmd.RealArgs[2]));
                        ew.Write(vec);
                        offset += 4;
                        break;

                    case G3dCommand.Color:
                        var color = GFXUtil.ConvertColorFormat(
                            (uint)Color.FromArgb(0, (int)cmd.IntArgs[0], (int)cmd.IntArgs[1],
                                                 (int)cmd.IntArgs[2]).ToArgb(),
                            ColorFormat.ARGB8888, ColorFormat.ABGR1555);
                        ew.Write(color);
                        offset += 4;
                        break;

                    case G3dCommand.Vertex:
                        ew.WriteFx16s(cmd.RealArgs);
                        ew.Write((ushort)0);
                        offset += 8;
                        break;
                    }
                }

                if (param0Flag)
                {
                    ew.Write(0);
                    offset += 4;

                    param0Flag = false;
                }
            }

            foreach (var command in cmdList)
            {
                if (command.G3dCommand != G3dCommand.Nop)
                {
                    param0Flag = packed > 0 && (command.G3dCommand == G3dCommand.Identity ||
                                                command.G3dCommand == G3dCommand.PushMatrix ||
                                                command.G3dCommand == G3dCommand.End);
                }

                //m.Position = offset;

                commandQueue.Enqueue(command);
                ew.Write((byte)command.G3dCommand);
                packed++;
                offset++;

                if (packed == 4)
                {
                    Flush();
                }
            }

            var dl = m.ToArray();

            m.Close();

            return(dl);
        }
예제 #22
0
 public void Color(uint color)
 {
     Color(System.Drawing.Color.FromArgb((int)GFXUtil.ConvertColorFormat(color, ColorFormat.XBGR1555, ColorFormat.ARGB8888)));
 }
예제 #23
0
        public static List <DisplayListCommand> Decode(byte[] dl)
        {
            var m  = new MemoryStream(dl);
            var er = new EndianBinaryReaderEx(m, Endianness.LittleEndian);

            var commandQueue = new Queue <G3dCommand>();

            var decoded = new List <DisplayListCommand>();

            while (m.Position < dl.Length)
            {
                commandQueue.Enqueue((G3dCommand)er.ReadByte());
                commandQueue.Enqueue((G3dCommand)er.ReadByte());
                commandQueue.Enqueue((G3dCommand)er.ReadByte());
                commandQueue.Enqueue((G3dCommand)er.ReadByte());

                //Decode the 4 enqueued commands
                for (var j = 0; j < 4; j++)
                {
                    var cmd = commandQueue.Dequeue();

                    switch (cmd)
                    {
                    default:
                    case G3dCommand.PushMatrix:
                    case G3dCommand.End:
                        decoded.Add(new DisplayListCommand {
                            G3dCommand = cmd
                        });
                        break;

                    case G3dCommand.TexCoord:
                        decoded.Add(new DisplayListCommand
                        {
                            G3dCommand = cmd,
                            RealArgs   = new[]
                            {
                                er.ReadFixedPoint(true, 11, 4),
                                er.ReadFixedPoint(true, 11, 4)
                            }
                        });
                        break;

                    case G3dCommand.VertexXY:
                    case G3dCommand.VertexXZ:
                    case G3dCommand.VertexYZ:
                        decoded.Add(new DisplayListCommand {
                            G3dCommand = cmd, RealArgs = er.ReadFx16s(2)
                        });
                        break;

                    case G3dCommand.Begin:
                    case G3dCommand.RestoreMatrix:
                        decoded.Add(new DisplayListCommand {
                            G3dCommand = cmd, IntArgs = er.ReadUInt32s(1)
                        });
                        break;

                    case G3dCommand.VertexDiff:
                        var vec2 = VecFx10.ToVector3(er.ReadUInt32()) / 8;
                        decoded.Add(new DisplayListCommand {
                            G3dCommand = cmd, RealArgs = new[] { vec2.X, vec2.Y, vec2.Z }
                        });
                        break;

                    case G3dCommand.VertexShort:
                        var vec3 = VecFx10.ToVector3(er.ReadUInt32(), 3, 6);
                        decoded.Add(new DisplayListCommand {
                            G3dCommand = cmd, RealArgs = new[] { vec3.X, vec3.Y, vec3.Z }
                        });
                        break;

                    case G3dCommand.Normal:
                        var vec = VecFx10.ToVector3(er.ReadUInt32());
                        decoded.Add(new DisplayListCommand {
                            G3dCommand = cmd, RealArgs = new[] { vec.X, vec.Y, vec.Z }
                        });
                        break;

                    case G3dCommand.Color:
                        var color = Color.FromArgb((int)GFXUtil.ConvertColorFormat(er.ReadUInt32(),
                                                                                   ColorFormat.ABGR1555, ColorFormat.ARGB8888));
                        decoded.Add(new DisplayListCommand {
                            G3dCommand = cmd, IntArgs = new uint[] { color.R, color.G, color.B }
                        });
                        break;

                    case G3dCommand.Vertex:
                        decoded.Add(new DisplayListCommand
                        {
                            G3dCommand = cmd,
                            RealArgs   = er.ReadFx16s(3)
                        });
                        er.ReadUInt16();
                        break;
                    }
                }
            }

            m.Close();

            return(decoded);
        }
예제 #24
0
        public static unsafe Bitmap ToBitmap(byte[] Data, int Offset, int Width, int Height, ImageFormat Format, TileMode TileMode, uint SwizzleMode, bool ExactSize = false)
        {
            if (Data == null || Data.Length < 1 || Offset < 0 || Offset >= Data.Length || Width < 1 || Height < 1)
            {
                return(null);
            }
            if (ExactSize && ((Width % 8) != 0 || (Height % 8) != 0))
            {
                return(null);
            }
            int physicalwidth  = Width;
            int physicalheight = Height;

            if (!ExactSize)
            {
                Width  = 1 << (int)Math.Ceiling(Math.Log(Width, 2));
                Height = 1 << (int)Math.Ceiling(Math.Log(Height, 2));
            }
            Bitmap     bitm   = new Bitmap(Width, Height);//physicalwidth, physicalheight);
            BitmapData d      = bitm.LockBits(new Rectangle(0, 0, bitm.Width, bitm.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
            uint *     res    = (uint *)d.Scan0;
            int        offs   = Offset;//0;
            int        stride = d.Stride / 4;

            switch (Format)
            {
            case ImageFormat.RGB565:
                for (int y = 0; y < Height; y++)
                {
                    for (int x = 0; x < Width; x++)
                    {
                        //if (x >= physicalwidth) continue;
                        if (y >= physicalheight)
                        {
                            continue;
                        }
                        res[y * stride + x] =
                            GFXUtil.ConvertColorFormat(
                                IOUtil.ReadU16LE(Data, offs),
                                ColorFormat.RGB565,
                                ColorFormat.ARGB8888);
                        offs += 2;
                    }
                }
                break;

            case ImageFormat.DXT5:
                for (int y2 = 0; y2 < Height; y2 += 4)
                {
                    for (int x2 = 0; x2 < Width; x2 += 4)
                    {
                        ulong  a_data       = IOUtil.ReadU64LE(Data, offs);
                        byte[] AlphaPalette = new byte[8];
                        AlphaPalette[0] = (byte)(a_data & 0xFF);
                        AlphaPalette[1] = (byte)((a_data >> 8) & 0xFF);
                        a_data        >>= 16;
                        if (AlphaPalette[0] > AlphaPalette[1])
                        {
                            AlphaPalette[2] = (byte)((6 * AlphaPalette[0] + 1 * AlphaPalette[1]) / 7);
                            AlphaPalette[3] = (byte)((5 * AlphaPalette[0] + 2 * AlphaPalette[1]) / 7);
                            AlphaPalette[4] = (byte)((4 * AlphaPalette[0] + 3 * AlphaPalette[1]) / 7);
                            AlphaPalette[5] = (byte)((3 * AlphaPalette[0] + 4 * AlphaPalette[1]) / 7);
                            AlphaPalette[6] = (byte)((2 * AlphaPalette[0] + 5 * AlphaPalette[1]) / 7);
                            AlphaPalette[7] = (byte)((1 * AlphaPalette[0] + 6 * AlphaPalette[1]) / 7);
                        }
                        else
                        {
                            AlphaPalette[2] = (byte)((4 * AlphaPalette[0] + 1 * AlphaPalette[1]) / 5);
                            AlphaPalette[3] = (byte)((3 * AlphaPalette[0] + 2 * AlphaPalette[1]) / 5);
                            AlphaPalette[4] = (byte)((2 * AlphaPalette[0] + 3 * AlphaPalette[1]) / 5);
                            AlphaPalette[5] = (byte)((1 * AlphaPalette[0] + 4 * AlphaPalette[1]) / 5);
                            AlphaPalette[6] = 0;
                            AlphaPalette[7] = 255;
                        }
                        offs += 8;
                        ushort color0  = IOUtil.ReadU16LE(Data, offs);
                        ushort color1  = IOUtil.ReadU16LE(Data, offs + 2);
                        uint   data    = IOUtil.ReadU32LE(Data, offs + 4);
                        uint[] Palette = new uint[4];
                        Palette[0] = GFXUtil.ConvertColorFormat(color0, ColorFormat.RGB565, ColorFormat.ARGB8888);
                        Palette[1] = GFXUtil.ConvertColorFormat(color1, ColorFormat.RGB565, ColorFormat.ARGB8888);
                        Color a = System.Drawing.Color.FromArgb((int)Palette[0]);
                        Color b = System.Drawing.Color.FromArgb((int)Palette[1]);
                        if (color0 > color1)    //1/3 and 2/3
                        {
                            Palette[2] = GFXUtil.ToColorFormat((a.R * 2 + b.R * 1) / 3, (a.G * 2 + b.G * 1) / 3, (a.B * 2 + b.B * 1) / 3, ColorFormat.ARGB8888);
                            Palette[3] = GFXUtil.ToColorFormat((a.R * 1 + b.R * 2) / 3, (a.G * 1 + b.G * 2) / 3, (a.B * 1 + b.B * 2) / 3, ColorFormat.ARGB8888);
                        }
                        else    //1/2 and transparent
                        {
                            Palette[2] = GFXUtil.ToColorFormat((a.R + b.R) / 2, (a.G + b.G) / 2, (a.B + b.B) / 2, ColorFormat.ARGB8888);
                            Palette[3] = 0;
                        }

                        int q  = 30;
                        int aq = 45;
                        for (int y3 = 0; y3 < 4; y3++)
                        {
                            for (int x3 = 0; x3 < 4; x3++)
                            {
                                //if (x2 + x3 >= physicalwidth) continue;
                                if (y2 + y3 >= physicalheight)
                                {
                                    continue;
                                }
                                res[(y2 + y3) * stride + x2 + x3] = (Palette[(data >> q) & 3] & 0xFFFFFF) | ((uint)AlphaPalette[(a_data >> aq) & 7] << 24);
                                q  -= 2;
                                aq -= 3;
                            }
                        }
                        offs += 8;
                    }
                    //	}
                    //}
                }
                break;

                /*case ImageFormat.ETC1://Some reference: http://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt
                 * case ImageFormat.ETC1A4:
                 *  {
                 *      for (int y = 0; y < Height; y += 8)
                 *      {
                 *          for (int x = 0; x < Width; x += 8)
                 *          {
                 *              for (int i = 0; i < 8; i += 4)
                 *              {
                 *                  for (int j = 0; j < 8; j += 4)
                 *                  {
                 *                      ulong alpha = 0xFFFFFFFFFFFFFFFF;
                 *                      ulong data = IOUtil.ReadU64BE(Data, offs);
                 *                      if (Format == ImageFormat.ETC1A4)
                 *                      {
                 *                          offs += 8;
                 *                          alpha = IOUtil.ReadU64BE(Data, offs);
                 *                      }
                 *                      bool diffbit = ((data >> 33) & 1) == 1;
                 *                      bool flipbit = ((data >> 32) & 1) == 1; //0: |||, 1: |-|
                 *                      int r1, r2, g1, g2, b1, b2;
                 *                      if (diffbit) //'differential' mode
                 *                      {
                 *                          int r = (int)((data >> 59) & 0x1F);
                 *                          int g = (int)((data >> 51) & 0x1F);
                 *                          int b = (int)((data >> 43) & 0x1F);
                 *                          r1 = (r << 3) | ((r & 0x1C) >> 2);
                 *                          g1 = (g << 3) | ((g & 0x1C) >> 2);
                 *                          b1 = (b << 3) | ((b & 0x1C) >> 2);
                 *                          r += (int)((data >> 56) & 0x7) << 29 >> 29;
                 *                          g += (int)((data >> 48) & 0x7) << 29 >> 29;
                 *                          b += (int)((data >> 40) & 0x7) << 29 >> 29;
                 *                          r2 = (r << 3) | ((r & 0x1C) >> 2);
                 *                          g2 = (g << 3) | ((g & 0x1C) >> 2);
                 *                          b2 = (b << 3) | ((b & 0x1C) >> 2);
                 *                      }
                 *                      else //'individual' mode
                 *                      {
                 *                          r1 = (int)((data >> 60) & 0xF) * 0x11;
                 *                          g1 = (int)((data >> 52) & 0xF) * 0x11;
                 *                          b1 = (int)((data >> 44) & 0xF) * 0x11;
                 *                          r2 = (int)((data >> 56) & 0xF) * 0x11;
                 *                          g2 = (int)((data >> 48) & 0xF) * 0x11;
                 *                          b2 = (int)((data >> 40) & 0xF) * 0x11;
                 *                      }
                 *                      int Table1 = (int)((data >> 37) & 0x7);
                 *                      int Table2 = (int)((data >> 34) & 0x7);
                 *                      for (int y3 = 0; y3 < 4; y3++)
                 *                      {
                 *                          for (int x3 = 0; x3 < 4; x3++)
                 *                          {
                 *                              if (x + j + x3 >= physicalwidth) continue;
                 *                              if (y + i + y3 >= physicalheight) continue;
                 *
                 *                              int val = (int)((data >> (x3 * 4 + y3)) & 0x1);
                 *                              bool neg = ((data >> (x3 * 4 + y3 + 16)) & 0x1) == 1;
                 *                              uint c;
                 *                              if ((flipbit && y3 < 2) || (!flipbit && x3 < 2))
                 *                              {
                 *                                  int add = ETC1Modifiers[Table1, val] * (neg ? -1 : 1);
                 *                                  c = GFXUtil.ToColorFormat((byte)(((alpha >> ((x3 * 4 + y3) * 4)) & 0xF) * 0x11), (byte)ColorClamp(r1 + add), (byte)ColorClamp(g1 + add), (byte)ColorClamp(b1 + add), ColorFormat.ARGB8888);
                 *                              }
                 *                              else
                 *                              {
                 *                                  int add = ETC1Modifiers[Table2, val] * (neg ? -1 : 1);
                 *                                  c = GFXUtil.ToColorFormat((byte)(((alpha >> ((x3 * 4 + y3) * 4)) & 0xF) * 0x11), (byte)ColorClamp(r2 + add), (byte)ColorClamp(g2 + add), (byte)ColorClamp(b2 + add), ColorFormat.ARGB8888);
                 *                              }
                 *                              res[(i + y3) * stride + x + j + x3] = c;
                 *                          }
                 *                      }
                 *                      offs += 8;
                 *                  }
                 *              }
                 *          }
                 *          res += stride * 8;
                 *      }
                 *  }
                 *  break;
                 * */
            }
            Detile(res, stride, Width, Height, physicalwidth, physicalheight, TileMode);
            bitm.UnlockBits(d);
            return(bitm);
        }
예제 #25
0
        public static unsafe Bitmap ToBitmap(byte[] TexData, int TexOffset, byte[] PalData, int PalOffset, int Width, int Height, ImageFormat Format, PaletteFormat PalFormat, bool ExactSize = false)
        {
            Bitmap     bitm   = new Bitmap(Width, Height);
            BitmapData d      = bitm.LockBits(new Rectangle(0, 0, bitm.Width, bitm.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
            uint *     res    = (uint *)d.Scan0;
            int        offs   = TexOffset;
            int        stride = d.Stride / 4;

            switch (Format)
            {
            case ImageFormat.I4:
            {
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int y2 = 0; y2 < 8; y2++)
                        {
                            for (int x2 = 0; x2 < 8; x2 += 2)
                            {
                                byte I1 = (byte)((TexData[offs] >> 4) * 0x11);
                                byte I2 = (byte)((TexData[offs] & 0xF) * 0x11);
                                res[(y + y2) * stride + x + x2]     = GFXUtil.ToColorFormat(I1, I1, I1, ColorFormat.ARGB8888);
                                res[(y + y2) * stride + x + x2 + 1] = GFXUtil.ToColorFormat(I2, I2, I2, ColorFormat.ARGB8888);
                                offs++;
                            }
                        }
                    }
                }
                break;
            }

            case ImageFormat.I8:
            {
                for (int y = 0; y < Height; y += 4)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int y2 = 0; y2 < 4; y2++)
                        {
                            for (int x2 = 0; x2 < 8; x2++)
                            {
                                byte I = TexData[offs];
                                res[(y + y2) * stride + x + x2] = GFXUtil.ToColorFormat(I, I, I, ColorFormat.ARGB8888);
                                offs++;
                            }
                        }
                    }
                }
                break;
            }

            case ImageFormat.IA4:
            {
                for (int y = 0; y < Height; y += 4)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int y2 = 0; y2 < 4; y2++)
                        {
                            for (int x2 = 0; x2 < 8; x2++)
                            {
                                byte I = (byte)((TexData[offs] & 0xF) * 0x11);
                                byte A = (byte)((TexData[offs] >> 4) * 0x11);
                                res[(y + y2) * stride + x + x2] = GFXUtil.ToColorFormat(A, I, I, I, ColorFormat.ARGB8888);
                                offs++;
                            }
                        }
                    }
                }
                break;
            }

            case ImageFormat.IA8:
            {
                for (int y = 0; y < Height; y += 4)
                {
                    for (int x = 0; x < Width; x += 4)
                    {
                        for (int y2 = 0; y2 < 4; y2++)
                        {
                            for (int x2 = 0; x2 < 4; x2++)
                            {
                                byte I = TexData[offs + 1];
                                byte A = TexData[offs];
                                res[(y + y2) * stride + x + x2] = GFXUtil.ToColorFormat(A, I, I, I, ColorFormat.ARGB8888);
                                offs += 2;
                            }
                        }
                    }
                }
                break;
            }

            case ImageFormat.RGB565:
            {
                for (int y = 0; y < Height; y += 4)
                {
                    for (int x = 0; x < Width; x += 4)
                    {
                        for (int y2 = 0; y2 < 4; y2++)
                        {
                            for (int x2 = 0; x2 < 4; x2++)
                            {
                                res[(y + y2) * stride + x + x2] =
                                    GFXUtil.ConvertColorFormat(
                                        IOUtil.ReadU16BE(TexData, offs),
                                        ColorFormat.RGB565,
                                        ColorFormat.ARGB8888);
                                //GFXUtil.RGB565ToArgb(IOUtil.ReadU16BE(TexData, offs));
                                offs += 2;
                            }
                        }
                    }
                }
                break;
            }

            case ImageFormat.RGB5A3:
            {
                for (int y = 0; y < Height; y += 4)
                {
                    for (int x = 0; x < Width; x += 4)
                    {
                        for (int y2 = 0; y2 < 4; y2++)
                        {
                            for (int x2 = 0; x2 < 4; x2++)
                            {
                                ushort data = IOUtil.ReadU16BE(TexData, offs);
                                if ((data & 0x8000) != 0)
                                {
                                    res[(y + y2) * stride + x + x2] =
                                        GFXUtil.ConvertColorFormat(data, ColorFormat.XRGB1555, ColorFormat.ARGB8888);
                                }
                                else
                                {
                                    res[(y + y2) * stride + x + x2] =
                                        GFXUtil.ConvertColorFormat(data, ColorFormat.ARGB3444, ColorFormat.ARGB8888);
                                }
                                offs += 2;
                            }
                        }
                    }
                }
                break;
            }

            case ImageFormat.CI4:
            {
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int y2 = 0; y2 < 8; y2++)
                        {
                            for (int x2 = 0; x2 < 8; x2 += 2)
                            {
                                byte index1 = (byte)(TexData[offs] >> 4);
                                byte index2 = (byte)(TexData[offs] & 0xF);
                                switch (PalFormat)
                                {
                                case PaletteFormat.RGB5A3:
                                {
                                    ushort data = IOUtil.ReadU16BE(PalData, PalOffset + index1 * 2);
                                    if ((data & 0x8000) != 0)
                                    {
                                        res[(y + y2) * stride + x + x2] =
                                            GFXUtil.ConvertColorFormat(data, ColorFormat.XRGB1555, ColorFormat.ARGB8888);
                                    }
                                    else
                                    {
                                        res[(y + y2) * stride + x + x2] =
                                            GFXUtil.ConvertColorFormat(data, ColorFormat.ARGB3444, ColorFormat.ARGB8888);
                                    }
                                    data = IOUtil.ReadU16BE(PalData, PalOffset + index2 * 2);
                                    if ((data & 0x8000) != 0)
                                    {
                                        res[(y + y2) * stride + x + x2 + 1] =
                                            GFXUtil.ConvertColorFormat(data, ColorFormat.XRGB1555, ColorFormat.ARGB8888);
                                    }
                                    else
                                    {
                                        res[(y + y2) * stride + x + x2 + 1] =
                                            GFXUtil.ConvertColorFormat(data, ColorFormat.ARGB3444, ColorFormat.ARGB8888);
                                    }
                                    break;
                                }
                                }
                                offs++;
                            }
                        }
                    }
                }
                break;
            }

            case ImageFormat.CI8:
            {
                for (int y = 0; y < Height; y += 4)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int y2 = 0; y2 < 4; y2++)
                        {
                            for (int x2 = 0; x2 < 8; x2++)
                            {
                                byte index = TexData[offs];
                                switch (PalFormat)
                                {
                                case PaletteFormat.RGB5A3:
                                {
                                    ushort data = IOUtil.ReadU16BE(PalData, PalOffset + index * 2);
                                    if ((data & 0x8000) != 0)
                                    {
                                        res[(y + y2) * stride + x + x2] =
                                            GFXUtil.ConvertColorFormat(data, ColorFormat.XRGB1555, ColorFormat.ARGB8888);
                                    }
                                    else
                                    {
                                        res[(y + y2) * stride + x + x2] =
                                            GFXUtil.ConvertColorFormat(data, ColorFormat.ARGB3444, ColorFormat.ARGB8888);
                                    }
                                    break;
                                }
                                }
                                offs++;
                            }
                        }
                    }
                }
                break;
            }

            case ImageFormat.CMP:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int y2 = 0; y2 < 8; y2 += 4)
                        {
                            for (int x2 = 0; x2 < 8; x2 += 4)
                            {
                                ushort color0  = IOUtil.ReadU16BE(TexData, offs);
                                ushort color1  = IOUtil.ReadU16BE(TexData, offs + 2);
                                uint   data    = IOUtil.ReadU32BE(TexData, offs + 4);
                                uint[] Palette = new uint[4];
                                Palette[0] = GFXUtil.ConvertColorFormat(color0, ColorFormat.RGB565, ColorFormat.ARGB8888);
                                Palette[1] = GFXUtil.ConvertColorFormat(color1, ColorFormat.RGB565, ColorFormat.ARGB8888);
                                Color a = Color.FromArgb((int)Palette[0]);
                                Color b = Color.FromArgb((int)Palette[1]);
                                if (color0 > color1)                                        //1/3 and 2/3
                                {
                                    Palette[2] = GFXUtil.ToColorFormat((a.R * 2 + b.R * 1) / 3, (a.G * 2 + b.G * 1) / 3, (a.B * 2 + b.B * 1) / 3, ColorFormat.ARGB8888);
                                    Palette[3] = GFXUtil.ToColorFormat((a.R * 1 + b.R * 2) / 3, (a.G * 1 + b.G * 2) / 3, (a.B * 1 + b.B * 2) / 3, ColorFormat.ARGB8888);
                                }
                                else                                        //1/2 and transparent
                                {
                                    Palette[2] = GFXUtil.ToColorFormat((a.R + b.R) / 2, (a.G + b.G) / 2, (a.B + b.B) / 2, ColorFormat.ARGB8888);
                                    Palette[3] = 0;
                                }

                                int q = 30;
                                for (int y3 = 0; y3 < 4; y3++)
                                {
                                    for (int x3 = 0; x3 < 4; x3++)
                                    {
                                        res[(y + y2 + y3) * stride + x + x2 + x3] = Palette[(data >> q) & 3];
                                        q -= 2;
                                    }
                                }
                                offs += 8;
                            }
                        }
                    }
                }
                break;
            }
            bitm.UnlockBits(d);
            return(bitm);
        }
예제 #26
0
        public static unsafe byte[] FromBitmap(Bitmap Picture, TextureFormat Format, bool ExactSize = false)
        {
            if (ExactSize && ((Picture.Width % 8) != 0 || (Picture.Height % 8) != 0))
            {
                return(null);
            }
            int physicalwidth  = Picture.Width;
            int physicalheight = Picture.Height;
            int ConvWidth      = Picture.Width;
            int ConvHeight     = Picture.Height;

            if (!ExactSize)
            {
                ConvWidth  = 1 << (int)Math.Ceiling(Math.Log(Picture.Width, 2));
                ConvHeight = 1 << (int)Math.Ceiling(Math.Log(Picture.Height, 2));
            }
            BitmapData d   = Picture.LockBits(new Rectangle(0, 0, Picture.Width, Picture.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            uint *     res = (uint *)d.Scan0;

            byte[] result = new byte[ConvWidth * ConvHeight * GetBpp(Format) / 8];
            int    offs   = 0;

            switch (Format)
            {
            case TextureFormat.Rgba8:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[(x2 % 4) + (y2 % 4) * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);

                            if ((y + y2) * d.Stride / 4 + x + x2 > d.Height * d.Stride)
                            {
                                Console.WriteLine("{0} > {1} overflow", (y + y2) * d.Stride / 4 + x + x2, d.Height * d.Stride);
                                Environment.Exit(1);
                            }

                            Color c = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);

                            // magic line. removing this causes the white boxes to go away, but every texture gets a black outline
                            if (c == Color.FromArgb(0, 0, 0, 0))
                            {
                                c = Color.FromArgb(0, 0xff, 0xff, 0xff);
                            }

                            result[offs + pos * 4 + 0] = c.A;
                            result[offs + pos * 4 + 1] = c.B;
                            result[offs + pos * 4 + 2] = c.G;
                            result[offs + pos * 4 + 3] = c.R;
                        }
                        offs += 64 * 4;
                    }
                }
                break;

            case TextureFormat.Rgb8:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int   pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            Color c   = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);
                            result[offs + pos * 3 + 0] = c.B;
                            result[offs + pos * 3 + 1] = c.G;
                            result[offs + pos * 3 + 2] = c.R;
                        }
                        offs += 64 * 3;
                    }
                }
                break;

            case TextureFormat.Rgb565:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            IOUtil.WriteU16LE(result, offs + pos * 2, (ushort)GFXUtil.ConvertColorFormat(res[(y + y2) * d.Stride / 4 + x + x2], ColorFormat.ARGB8888, ColorFormat.RGB565));     //GFXUtil.ArgbToRGB565(res[(y + y2) * d.Stride / 4 + x + x2]));
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case TextureFormat.Rgba4:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[(x2 % 4) + (y2 % 4) * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            IOUtil.WriteU16LE(result, offs + pos * 2, (ushort)GFXUtil.ConvertColorFormat(res[(y + y2) * d.Stride / 4 + x + x2], ColorFormat.ARGB8888, ColorFormat.RGBA4444));
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case TextureFormat.La8:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int   pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            Color c   = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);

                            result[offs + pos * 2 + 0] = c.A;
                            result[offs + pos * 2 + 1] = c.R;
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case TextureFormat.Hilo8:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int   pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            Color c   = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);

                            result[offs + pos * 2 + 0] = c.R;
                            result[offs + pos * 2 + 1] = c.G;
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case TextureFormat.L8:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int   pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            Color c   = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);

                            result[offs + pos * 1 + 0] = c.R;
                        }
                        offs += 64 * 1;
                    }
                }
                break;

            case TextureFormat.A8:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int   pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            Color c   = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]);

                            result[offs + pos * 1 + 0] = c.A;
                        }
                        offs += 64 * 1;
                    }
                }
                break;

            case TextureFormat.Etc1:
            case TextureFormat.Etc1A4:
                for (int y = 0; y < ConvHeight; y += 8)
                {
                    for (int x = 0; x < ConvWidth; x += 8)
                    {
                        for (int i = 0; i < 8; i += 4)
                        {
                            for (int j = 0; j < 8; j += 4)
                            {
                                if (Format == TextureFormat.Etc1A4)
                                {
                                    ulong alpha = 0;
                                    int   iiii  = 0;
                                    for (int xx = 0; xx < 4; xx++)
                                    {
                                        for (int yy = 0; yy < 4; yy++)
                                        {
                                            uint color;
                                            if (x + j + xx >= physicalwidth)
                                            {
                                                color = 0x00FFFFFF;
                                            }
                                            else if (y + i + yy >= physicalheight)
                                            {
                                                color = 0x00FFFFFF;
                                            }
                                            else
                                            {
                                                color = res[((y + i + yy) * (d.Stride / 4)) + x + j + xx];
                                            }
                                            uint a = color >> 24;
                                            a    >>= 4;
                                            alpha |= (ulong)a << (iiii * 4);
                                            iiii++;
                                        }
                                    }
                                    IOUtil.WriteU64LE(result, offs, alpha);
                                    offs += 8;
                                }
                                Color[] pixels = new Color[4 * 4];
                                for (int yy = 0; yy < 4; yy++)
                                {
                                    for (int xx = 0; xx < 4; xx++)
                                    {
                                        if (x + j + xx >= physicalwidth)
                                        {
                                            pixels[yy * 4 + xx] = Color.Transparent;
                                        }
                                        else if (y + i + yy >= physicalheight)
                                        {
                                            pixels[yy * 4 + xx] = Color.Transparent;
                                        }
                                        else
                                        {
                                            pixels[yy * 4 + xx] = Color.FromArgb((int)res[((y + i + yy) * (d.Stride / 4)) + x + j + xx]);
                                        }
                                    }
                                }
                                IOUtil.WriteU64LE(result, offs, ETC1.GenETC1(pixels));
                                offs += 8;
                            }
                        }
                    }
                }
                break;

            default:
                throw new NotImplementedException("This format is not implemented yet.");
            }
            return(result);
        }
예제 #27
0
        public static unsafe Bitmap ToBitmap(byte[] Data, int Offset, int Width, int Height, ImageFormat Format, bool ExactSize = false)
        {
            if (Data == null || Data.Length < 1 || Offset < 0 || Offset >= Data.Length || Width < 1 || Height < 1)
            {
                return(null);
            }
            if (ExactSize && ((Width % 8) != 0 || (Height % 8) != 0))
            {
                return(null);
            }
            int physicalwidth  = Width;
            int physicalheight = Height;

            if (!ExactSize)
            {
                Width  = 1 << (int)Math.Ceiling(Math.Log(Width, 2));
                Height = 1 << (int)Math.Ceiling(Math.Log(Height, 2));
            }
            Bitmap     bitm   = new Bitmap(physicalwidth, physicalheight);
            BitmapData d      = bitm.LockBits(new Rectangle(0, 0, bitm.Width, bitm.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
            uint *     res    = (uint *)d.Scan0;
            int        offs   = Offset;//0;
            int        stride = d.Stride / 4;

            switch (Format)
            {
            case ImageFormat.RGBA8:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            res[(y + y2) * stride + x + x2] =
                                GFXUtil.ConvertColorFormat(
                                    IOUtil.ReadU32LE(Data, offs + pos * 4),
                                    ColorFormat.RGBA8888,
                                    ColorFormat.ARGB8888);

                            /*GFXUtil.ToArgb(
                             *                              Data[offs + pos * 4],
                             *                              Data[offs + pos * 4 + 3],
                             *                              Data[offs + pos * 4 + 2],
                             *                              Data[offs + pos * 4 + 1]
                             *                              );*/
                        }
                        offs += 64 * 4;
                    }
                }
                break;

            case ImageFormat.RGB8:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            res[(y + y2) * stride + x + x2] =
                                GFXUtil.ConvertColorFormat(
                                    IOUtil.ReadU24LE(Data, offs + pos * 3),
                                    ColorFormat.RGB888,
                                    ColorFormat.ARGB8888);

                            /*GFXUtil.ToArgb(
                             *                              Data[offs + pos * 3 + 2],
                             *                              Data[offs + pos * 3 + 1],
                             *                              Data[offs + pos * 3 + 0]
                             *                              );*/
                        }
                        offs += 64 * 3;
                    }
                }
                break;

            case ImageFormat.RGBA5551:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            res[(y + y2) * stride + x + x2] =
                                GFXUtil.ConvertColorFormat(
                                    IOUtil.ReadU16LE(Data, offs + pos * 2),
                                    ColorFormat.RGBA5551,
                                    ColorFormat.ARGB8888);
                            //GFXUtil.RGBA5551ToArgb(IOUtil.ReadU16LE(Data, offs + pos * 2));
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case ImageFormat.RGB565:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            res[(y + y2) * stride + x + x2] =
                                GFXUtil.ConvertColorFormat(
                                    IOUtil.ReadU16LE(Data, offs + pos * 2),
                                    ColorFormat.RGB565,
                                    ColorFormat.ARGB8888);
                            //GFXUtil.RGB565ToArgb(IOUtil.ReadU16LE(Data, offs + pos * 2));
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case ImageFormat.RGBA4:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            res[(y + y2) * stride + x + x2] =
                                GFXUtil.ConvertColorFormat(
                                    IOUtil.ReadU16LE(Data, offs + pos * 2),
                                    ColorFormat.RGBA4444,
                                    ColorFormat.ARGB8888);

                            /*GFXUtil.ToArgb(
                             *                              (byte)((Data[offs + pos * 2] & 0xF) * 0x11),
                             *                              (byte)((Data[offs + pos * 2 + 1] >> 4) * 0x11),
                             *                              (byte)((Data[offs + pos * 2 + 1] & 0xF) * 0x11),
                             *                              (byte)((Data[offs + pos * 2] >> 4) * 0x11)
                             *                              );*/
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case ImageFormat.LA8:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            res[(y + y2) * stride + x + x2] = GFXUtil.ToColorFormat(
                                Data[offs + pos * 2],
                                Data[offs + pos * 2 + 1],
                                Data[offs + pos * 2 + 1],
                                Data[offs + pos * 2 + 1],
                                ColorFormat.ARGB8888
                                );
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case ImageFormat.HILO8:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            res[(y + y2) * stride + x + x2] = GFXUtil.ToColorFormat(
                                Data[offs + pos * 2],
                                Data[offs + pos * 2 + 1],
                                Data[offs + pos * 2 + 1],
                                Data[offs + pos * 2 + 1],
                                ColorFormat.ARGB8888
                                );
                        }
                        offs += 64 * 2;
                    }
                }
                break;

            case ImageFormat.L8:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            res[(y + y2) * stride + x + x2] = GFXUtil.ToColorFormat(
                                Data[offs + pos],
                                Data[offs + pos],
                                Data[offs + pos],
                                ColorFormat.ARGB8888
                                );
                        }
                        offs += 64;
                    }
                }
                break;

            case ImageFormat.A8:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            res[(y + y2) * stride + x + x2] = GFXUtil.ToColorFormat(
                                Data[offs + pos],
                                255,
                                255,
                                255,
                                ColorFormat.ARGB8888
                                );
                        }
                        offs += 64;
                    }
                }
                break;

            case ImageFormat.LA4:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            res[(y + y2) * stride + x + x2] = GFXUtil.ToColorFormat(
                                (byte)((Data[offs + pos] & 0xF) * 0x11),
                                (byte)((Data[offs + pos] >> 4) * 0x11),
                                (byte)((Data[offs + pos] >> 4) * 0x11),
                                (byte)((Data[offs + pos] >> 4) * 0x11),
                                ColorFormat.ARGB8888
                                );
                        }
                        offs += 64;
                    }
                }
                break;

            case ImageFormat.L4:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos   = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            int shift = (pos & 1) * 4;
                            res[(y + y2) * stride + x + x2] = GFXUtil.ToColorFormat(
                                (byte)(((Data[offs + pos / 2] >> shift) & 0xF) * 0x11),
                                (byte)(((Data[offs + pos / 2] >> shift) & 0xF) * 0x11),
                                (byte)(((Data[offs + pos / 2] >> shift) & 0xF) * 0x11),
                                ColorFormat.ARGB8888
                                );
                        }
                        offs += 64 / 2;
                    }
                }
                break;

            case ImageFormat.A4:
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int x2 = i % 8;
                            if (x + x2 >= physicalwidth)
                            {
                                continue;
                            }
                            int y2 = i / 8;
                            if (y + y2 >= physicalheight)
                            {
                                continue;
                            }
                            int pos   = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4);
                            int shift = (pos & 1) * 4;
                            res[(y + y2) * stride + x + x2] = GFXUtil.ToColorFormat(
                                (byte)(((Data[offs + pos / 2] >> shift) & 0xF) * 0x11),
                                255,
                                255,
                                255,
                                ColorFormat.ARGB8888
                                );
                        }
                        offs += 64 / 2;
                    }
                }
                break;

            case ImageFormat.ETC1:    //Some reference: http://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt
            case ImageFormat.ETC1A4:
            {
                for (int y = 0; y < Height; y += 8)
                {
                    for (int x = 0; x < Width; x += 8)
                    {
                        for (int i = 0; i < 8; i += 4)
                        {
                            for (int j = 0; j < 8; j += 4)
                            {
                                ulong alpha = 0xFFFFFFFFFFFFFFFF;
                                if (Format == ImageFormat.ETC1A4)
                                {
                                    alpha = IOUtil.ReadU64LE(Data, offs);
                                    offs += 8;
                                }
                                ulong data = IOUtil.ReadU64LE(Data, offs);
                                bool  diffbit = ((data >> 33) & 1) == 1;
                                bool  flipbit = ((data >> 32) & 1) == 1; //0: |||, 1: |-|
                                int   r1, r2, g1, g2, b1, b2;
                                if (diffbit)                             //'differential' mode
                                {
                                    int r = (int)((data >> 59) & 0x1F);
                                    int g = (int)((data >> 51) & 0x1F);
                                    int b = (int)((data >> 43) & 0x1F);
                                    r1 = (r << 3) | ((r & 0x1C) >> 2);
                                    g1 = (g << 3) | ((g & 0x1C) >> 2);
                                    b1 = (b << 3) | ((b & 0x1C) >> 2);
                                    r += (int)((data >> 56) & 0x7) << 29 >> 29;
                                    g += (int)((data >> 48) & 0x7) << 29 >> 29;
                                    b += (int)((data >> 40) & 0x7) << 29 >> 29;
                                    r2 = (r << 3) | ((r & 0x1C) >> 2);
                                    g2 = (g << 3) | ((g & 0x1C) >> 2);
                                    b2 = (b << 3) | ((b & 0x1C) >> 2);
                                }
                                else         //'individual' mode
                                {
                                    r1 = (int)((data >> 60) & 0xF) * 0x11;
                                    g1 = (int)((data >> 52) & 0xF) * 0x11;
                                    b1 = (int)((data >> 44) & 0xF) * 0x11;
                                    r2 = (int)((data >> 56) & 0xF) * 0x11;
                                    g2 = (int)((data >> 48) & 0xF) * 0x11;
                                    b2 = (int)((data >> 40) & 0xF) * 0x11;
                                }
                                int Table1 = (int)((data >> 37) & 0x7);
                                int Table2 = (int)((data >> 34) & 0x7);
                                for (int y3 = 0; y3 < 4; y3++)
                                {
                                    for (int x3 = 0; x3 < 4; x3++)
                                    {
                                        if (x + j + x3 >= physicalwidth)
                                        {
                                            continue;
                                        }
                                        if (y + i + y3 >= physicalheight)
                                        {
                                            continue;
                                        }

                                        int  val = (int)((data >> (x3 * 4 + y3)) & 0x1);
                                        bool neg = ((data >> (x3 * 4 + y3 + 16)) & 0x1) == 1;
                                        uint c;
                                        if ((flipbit && y3 < 2) || (!flipbit && x3 < 2))
                                        {
                                            int add = ETC1Modifiers[Table1, val] * (neg ? -1 : 1);
                                            c = GFXUtil.ToColorFormat((byte)(((alpha >> ((x3 * 4 + y3) * 4)) & 0xF) * 0x11), (byte)ColorClamp(r1 + add), (byte)ColorClamp(g1 + add), (byte)ColorClamp(b1 + add), ColorFormat.ARGB8888);
                                        }
                                        else
                                        {
                                            int add = ETC1Modifiers[Table2, val] * (neg ? -1 : 1);
                                            c = GFXUtil.ToColorFormat((byte)(((alpha >> ((x3 * 4 + y3) * 4)) & 0xF) * 0x11), (byte)ColorClamp(r2 + add), (byte)ColorClamp(g2 + add), (byte)ColorClamp(b2 + add), ColorFormat.ARGB8888);
                                        }
                                        res[(i + y3) * stride + x + j + x3] = c;
                                    }
                                }
                                offs += 8;
                            }
                        }
                    }
                    res += stride * 8;
                }
            }
            break;
            }
            bitm.UnlockBits(d);
            return(bitm);
        }
예제 #28
0
        public override void DrawCircle(double cx, double cy, double radius)
        {
            if (thinlinemode != ThinLineModeFlag.OwnThinLines)
            {
                base.DrawCircle(cx, cy, radius);
                return;
            }


            stipplebit = 0x8000;
            int nx = 0, ny = 0, px = 0, py = 0;

            int buffersize = Clipper.ClipCircle(cx, cy, radius, clipbuffer, clipMinX, clipMinY, clipMaxX, clipMaxY);

            if (buffersize <= 0)
            {
                return;
            }

            if (buffersize >= 5) //circle is clipped to arcs
            {                    //the circle is divided into arc(s)
                double bulge, x1, y1, x2, y2;
                for (int l = 0; l < buffersize; l += 5)
                {
                    x1    = clipbuffer[l];
                    y1    = clipbuffer[l + 1];
                    x2    = clipbuffer[l + 2];
                    y2    = clipbuffer[l + 3];
                    bulge = clipbuffer[l + 4];

                    //draw arc here instead of calling DrawArc to avoid arc clipping because we already clipped!
                    GeomUtil.FlattenArc(x1, y1, x2, y2, bulge, true, flattentol, (x, y, moveto) =>
                    {
                        if (moveto)
                        {
                            px = GFXUtil.FloatToInt(x);
                            py = GFXUtil.FloatToInt(y);
                        }
                        else
                        {
                            nx = GFXUtil.FloatToInt(x);
                            ny = GFXUtil.FloatToInt(y);
                            Line_Internal(px, py, nx, ny, false);
                            px = nx;
                            py = ny;
                        }
                    });
                }

                return;
            }


            for (double l = -1; l <= 1.0001; l += 2)
            { //2 arcs gives circle  //TODO: make flatten circle in GeomUtil instead
                GeomUtil.FlattenArc(cx + radius * l, cy, cx - radius * l, cy, 1.0, true, flattentol, (x, y, moveto) =>
                {
                    if (moveto)
                    {
                        px = GFXUtil.FloatToInt(x);
                        py = GFXUtil.FloatToInt(y);
                    }
                    else
                    {
                        nx = GFXUtil.FloatToInt(x);
                        ny = GFXUtil.FloatToInt(y);
                        Line_Internal(px, py, nx, ny, false);
                        px = nx;
                        py = ny;
                    }
                });
            }
        }
예제 #29
0
 public void Color(uint color)
 {
     Color(System.Drawing.Color.FromArgb((int)GFXUtil.XBGR1555ToArgb((ushort)color)));
 }