http://bugs.winehq.org/show_bug.cgi?id=30126
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Component|-unknown |gdiplus
--- Comment #3 from Anastasius Focht focht@gmx.net 2012-03-10 09:21:24 CST --- Hello,
using .NET SDK/debugger, "Reflector" tool and Wine patches to enable managed debugging I was at least able to extract managed code sequence and parameters.
Unfortunately no IL debugging because this is already JIT compiled machine code at this point.
Starting with backtrace and parameters at exception:
--- snip --- (cordbg) w Thread 0x30 Current State:GCUnsafe spot 0)* (AD 'DistantWorlds.exe', #1) System.Drawing!System.Drawing.Bitmap::.ctor(V 1, size 47) +0104[native] +0039[IL] in <Unknown File Name>:<Unknown Line Number> width=0 height=0 format=(0x33d800) <System.Drawing.Imaging.PixelFormat> 1) (AD 'DistantWorlds.exe', #1) DistantWorlds!DistantWorlds.PlanetaryRingsGenerator::IP4s1vqiMTYbc(V 1, size 100) +0102[native] +0014[IL] in <Unknown File Name>:<Unknown Line Number> =(0x11a39fc) <System.Drawing.Bitmap> =(0x33d858) <System.Drawing.Rectangle> 2) (AD 'DistantWorlds.exe', #1) DistantWorlds!DistantWorlds.PlanetaryRingsGenerator::I5kqstLjxd9mGYbqaMBQ6MPMEDmSxAosD4j(V 1, size 26) +0127[native] +0009[IL] in <Unknown File Name>:<Unknown Line Number> =(0x11a39fc) <System.Drawing.Bitmap> =0 3) (AD 'DistantWorlds.exe', #1) DistantWorlds!DistantWorlds.PlanetaryRingsGenerator::I0dnVLPuf6uVarpxEFTlj2r(V 1, size 682) +1992[native] +0668[IL] in <Unknown File Name>:<Unknown Line Number> =(0x11a3028) <System.Drawing.Color[]> =-3.20360191431328 =1186 =196 =-1 4) (AD 'DistantWorlds.exe', #1) DistantWorlds!DistantWorlds.PlanetaryRingsGenerator::GenerateRings(V 1, size 296) +0671[native] +0283[IL] in <Unknown File Name>:<Unknown Line Number> seed=0 planetDiameter=700 5) (AD 'DistantWorlds.exe', #1) DistantWorlds!DistantWorlds.Main::IkVYGnH7jMvBhLaml(V 1, size 40) +0095[native] +0010[IL] in <Unknown File Name>:<Unknown Line Number> =(0x1070c90) "C:\Matrix Games\Distant Worlds\images" =0.5 6) (AD 'DistantWorlds.exe', #1) DistantWorlds!DistantWorlds.Main::IcAB016nyGW(V 1, size 224) +0234[native] +0100[IL] in <Unknown File Name>:<Unknown Line Number> 7) (AD 'DistantWorlds.exe', #1) DistantWorlds!DistantWorlds.Main::IbMqCLIMV3FlOXLEMWhP(V 1, size 11468) +9569[native] +4004[IL] in <Unknown File Name>:<Unknown Line Number> =1920 =1080 8) (AD 'DistantWorlds.exe', #1) DistantWorlds!DistantWorlds.Main::.ctor(V 1, size 2657) +6560[native] +2656[IL] in <Unknown File Name>:<Unknown Line Number> width=1920 height=1080 splashForm=(0xee0af4) <DistantWorlds.Splash> 9) (AD 'DistantWorlds.exe', #1) DistantWorlds!DistantWorlds.Start::Igr8wn8mM1WnLht2ycuMoxHGm0Eh4c(V 1, size 2829) +2361[native] +0833[IL] in <Unknown File Name>:<Unknown Line Number> =(0xe638dc) <DistantWorlds.Start> =(0xe634d4) <System.EventArgs> --- snip ---
DistantWorlds.PlanetaryRingsGenerator.GenerateRings -> DistantWorlds.PlanetaryRingsGenerator.I0dnVLPuf6uVarpxEFTlj2r
Input params:
--- snip --- num13 = -3.20360191431328 num11 = 1186 num12 = 196 num1 = -1 --- snip ---
num8 = 1186
--- snip --- private Bitmap I0dnVLPuf6uVarpxEFTlj2r(Color[] colorArray1, double num13, int num11, int num12, int num1) { if (num1 != -1) { this.IILC7Nv = num1; this.IOA7GLkiN9NHvPSGnRHCYsU = new Random(this.IILC7Nv); } int num = (int) ((int) (num11 * 0.22)); Bitmap image = new Bitmap(num11, num11, PixelFormat.Format32bppPArgb); Graphics graphics = Graphics.FromImage(image); graphics.set_CompositingQuality(CompositingQuality.HighSpeed); graphics.set_InterpolationMode(InterpolationMode.Bilinear); graphics.set_SmoothingMode(SmoothingMode.AntiAlias); SolidBrush brush = new SolidBrush(Color.Transparent); graphics.FillRectangle(brush, 0, 0, num12, num); int index = this.IOA7GLkiN9NHvPSGnRHCYsU.Next(0, (int) colorArray1.Length); int num3 = (int) ((int) ((num12 * 0.5) + ((num12 * this.IOA7GLkiN9NHvPSGnRHCYsU.NextDouble()) * 0.2))); Rectangle rectangle = this.Iro6aXBuEcuRl6K7sI8XXdXyuLQKgPrjsHSCqC(num11, num, num12, num3); Pen pen = new Pen(colorArray1[index], (float) num3); graphics.DrawEllipse(pen, rectangle); int num4 = this.IOA7GLkiN9NHvPSGnRHCYsU.Next(2, 6); for (int i = 0; i < num4; i = (int) (i + 1)) { index = this.IOA7GLkiN9NHvPSGnRHCYsU.Next(0, (int) colorArray1.Length); num3 = (int) ((int) ((num12 * 0.5) * this.IOA7GLkiN9NHvPSGnRHCYsU.NextDouble())); rectangle = this.Iro6aXBuEcuRl6K7sI8XXdXyuLQKgPrjsHSCqC(num11, num, num12, num3); pen = new Pen(colorArray1[index], (float) num3); graphics.DrawEllipse(pen, rectangle); } int num6 = this.IOA7GLkiN9NHvPSGnRHCYsU.Next(30, 50); for (int j = 0; j < num6; j = (int) (j + 1)) { index = this.IOA7GLkiN9NHvPSGnRHCYsU.Next(0, (int) colorArray1.Length); num3 = (int) (1 + this.IOA7GLkiN9NHvPSGnRHCYsU.Next(0, 2)); Color color = colorArray1[index]; rectangle = this.Iro6aXBuEcuRl6K7sI8XXdXyuLQKgPrjsHSCqC(num11, num, num12, num3); pen = new Pen(color, (float) num3); graphics.DrawEllipse(pen, rectangle); } Bitmap bitmap2 = new Bitmap(num11, num, PixelFormat.Format32bppPArgb); Graphics graphics2 = Graphics.FromImage(bitmap2); graphics2.set_InterpolationMode(InterpolationMode.HighQualityBilinear); graphics2.set_SmoothingMode(SmoothingMode.HighSpeed); graphics2.DrawImage(image, new Rectangle(0, 0, image.get_Width(), num), new Rectangle(0, 0, image.get_Width(), image.get_Height()), GraphicsUnit.Pixel); int num8 = Math.Max(bitmap2.get_Width(), bitmap2.get_Height()); Bitmap bitmap3 = new Bitmap(num8, num8, PixelFormat.Format32bppPArgb); Graphics graphics3 = Graphics.FromImage(bitmap3); int num9 = (int) ((num8 - bitmap2.get_Width()) / 2); int num10 = (int) ((num8 - bitmap2.get_Height()) / 2); graphics3.set_CompositingQuality(CompositingQuality.HighSpeed); graphics3.set_InterpolationMode(InterpolationMode.Bilinear); graphics3.set_SmoothingMode(SmoothingMode.HighSpeed); graphics3.DrawImage(bitmap2, num9, num10); bitmap2.Dispose(); bitmap3 = this.Igr8wn8mM1WnLht2ycuMoxHGm0Eh4c(bitmap3, (float) num13); return this.I5kqstLjxd9mGYbqaMBQ6MPMEDmSxAosD4j(bitmap3, 0); } --- snip ---
There is no error returned by gdiplus in various transformation/drawing operations prior creating the final "planetary rings" bitmap. It's a huge log filtering for gdiplus related calls alone.
num1 = 0
--- snip --- private Bitmap I5kqstLjxd9mGYbqaMBQ6MPMEDmSxAosD4j(Bitmap bitmap1, int num1) { Rectangle rectangle = this.IGNof4F(bitmap1, num1); Bitmap bitmap = this.IP4s1vqiMTYbc(bitmap1, rectangle); bitmap1.Dispose(); return bitmap; } ... private Rectangle IGNof4F(Bitmap bitmap1, int num1) { return this.ILRXNme(bitmap1, num1, Color.Empty, 0, 4); } ... private Rectangle ILRXNme(Bitmap bitmap1, int num14, Color color1, int num1, int num13) { Rectangle rectangle = new Rectangle(); FastBitmap bitmap = new FastBitmap(bitmap1); int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; bool flag = false; for (int i = 0; i < bitmap1.get_Width(); i = (int) (i + num13)) { for (int n = 0; n < bitmap1.get_Height(); n = (int) (n + num13)) { if (!color1.get_IsEmpty()) { Color pixel = bitmap.GetPixel(ref i, ref n); if (((pixel.get_R() <= (color1.get_R() + num1)) && (pixel.get_G() <= (color1.get_G() + num1))) && (pixel.get_B() <= (color1.get_B() + num1))) { continue; } num = Math.Max(0, (int) (i - num13)); flag = true; break; } if (bitmap.GetPixel(ref i, ref n).get_A() > num14) { num = Math.Max(0, (int) (i - num13)); flag = true; break; } } if (flag) { break; } } flag = false; for (int j = (int) (bitmap1.get_Width() - 1); j >= 0; j = (int) (j - num13)) { for (int num8 = 0; num8 < bitmap1.get_Height(); num8 = (int) (num8 + num13)) { if (!color1.get_IsEmpty()) { Color color2 = bitmap.GetPixel(ref j, ref num8); if (((color2.get_R() <= (color1.get_R() + num1)) && (color2.get_G() <= (color1.get_G() + num1))) && (color2.get_B() <= (color1.get_B() + num1))) { continue; } num2 = Math.Min((int) (bitmap1.get_Width() - 1), (int) (j + num13)); flag = true; break; } if (bitmap.GetPixel(ref j, ref num8).get_A() > num14) { num2 = Math.Min((int) (bitmap1.get_Width() - 1), (int) (j + num13)); flag = true; break; } } if (flag) { break; } } flag = false; for (int k = 0; k < bitmap1.get_Height(); k = (int) (k + num13)) { for (int num10 = 0; num10 < bitmap1.get_Width(); num10 = (int) (num10 + num13)) { if (!color1.get_IsEmpty()) { Color color3 = bitmap.GetPixel(ref num10, ref k); if (((color3.get_R() <= (color1.get_R() + num1)) && (color3.get_G() <= (color1.get_G() + num1))) && (color3.get_B() <= (color1.get_B() + num1))) { continue; } num3 = Math.Max(0, (int) (k - num13)); flag = true; break; } if (bitmap.GetPixel(ref num10, ref k).get_A() > num14) { num3 = Math.Max(0, (int) (k - num13)); flag = true; break; } } if (flag) { break; } } flag = false; for (int m = (int) (bitmap1.get_Height() - 1); m >= 0; m = (int) (m - num13)) { for (int num12 = 0; num12 < bitmap1.get_Width(); num12 = (int) (num12 + num13)) { if (!color1.get_IsEmpty()) { Color color4 = bitmap.GetPixel(ref num12, ref m); if (((color4.get_R() <= (color1.get_R() + num1)) && (color4.get_G() <= (color1.get_G() + num1))) && (color4.get_B() <= (color1.get_B() + num1))) { continue; } num4 = Math.Min((int) (bitmap1.get_Height() - 1), (int) (m + num13)); flag = true; break; } if (bitmap.GetPixel(ref num12, ref m).get_A() > num14) { num4 = Math.Min((int) (bitmap1.get_Height() - 1), (int) (m + num13)); flag = true; break; } } if (flag) { break; } } bitmap.Release(); return new Rectangle(num, num3, (int) (num2 - num), (int) (num4 - num3)); } --- snip ---
(FastBitmap seems to be a small internal wrapper class to access the pixel data directly)
An empty bounding rectangle is returned, maybe alpha/transparency issue or the pixel buffer content is wrong due to earlier operations.
One approach could be to reduce/transform the managed code snippets (C#) into small .NET executable to test/play with (Wine vs. native gdiplus).
Regards