https://bugzilla.novell.com/show_bug.cgi?id=642631
https://bugzilla.novell.com/show_bug.cgi?id=642631#c0 Summary: System.Drawing.Icon should recalculate the ImageOffset when the specified ico file has 256x256 image. Classification: Mono Product: Mono: Class Libraries Version: 2.6.x Platform: i686 OS/Version: Windows XP Status: NEW Severity: Normal Priority: P5 - None Component: Sys.Drawing. AssignedTo: [email protected] ReportedBy: [email protected] QAContact: [email protected] Found By: --- Blocker: --- User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:2.0b7pre) Gecko/20100928 Firefox/4.0b7pre SEE "STEPS TO REPRODUCE","ACTUAL RESULTS" and "EXPECTED RESULTS" Reproducible: Always Steps to Reproduce: 1. download the AnnCompact.ico and Ann.ico and put them under C:\ for the step 7 http://sourceforge.jp/projects/azuki/svn/view/trunk/Ann/Resources/?root=azuki 2. open AnnCompact.ico with a binary file editor. 3. understand the icon file format used before Vista. http://msdn.microsoft.com/en-us/library/ms997538.aspx you will see 6 ICONDIRENTRYs,starting from the address 0x00000006 to 0x00000065, 16 bytes each. ImageOffset of first ICONDIRENTRY is 0x00000066(Address: 0x00000012 to 0x00000015 in AnnCompact.ico) and the following 0x000002E8 bytes specified in BytesInRes(Address:0x0000000E to 0x00000011 in AnnCompact.ico) in first ICONDIRENTRY is ICONIMAGE for the first Image. 4. In Vista, an icon file may have 256x256 image stored in PNG format(Of course, no BITMAPINFOHEADER), starting from ImageOffset in its ICONDIRENTRY. ImageOffset for first ICONDIRENTRY is 0x00000076(Address: 0x00000012 to 0x00000015 in Ann.ico) Ann.ico is such an icon. You can understand if you open it with a binary file editor. 5. Read InitFromStreamWithSize called by the System.Drawing.Icon constructor. ICONDIRENTRYs are stored in a variable, except for ICONDIRENTRY of 256x256 image. Members of ICONDIRENTRY is read from stream and stored http://github.com/mono/mono/blob/master/mcs/class/System.Drawing/System.Drawing/Icon.cs#L635 6. Read SaveAll method. If I call the SaveAll method, the stored value is used WITHOUT ANY MODIFICATION. http://github.com/mono/mono/blob/master/mcs/class/System.Drawing/System.Drawing/Icon.cs#L358 7.Run the following Code. using System; namespace Icon { class MainClass { public static void Main (string[] args) { System.IO.FileStream ifs1 = new System.IO.FileStream("C:\\Ann.ico",System.IO.FileMode.Open); System.IO.FileStream ofs1 = new System.IO.FileStream("C:\\Ann.bin",System.IO.FileMode.Create); System.Drawing.Icon icon1 = new System.Drawing.Icon(ifs1); icon1.Save(ofs1); ifs1.Close(); ofs1.Close(); System.Console.WriteLine("Fin"); } } } 8. Open C:\Ann.bin with a binary file editor. 9. you will see 6 ICONDIRENTRYs, without the one for 256x256 image. ImageOffset for first ICONDIRENTRY is 0x00000076.(Address: 0x00000012 to 0x00000015 in Ann.bin) Actual Results: Described in "STEPS TO REPRODUCE" and "EXPECTED RESULTS" SECTIONS Expected Results: FOR ICONDIRENTRYs BEFORE THE ONE FOR 256x256 IMAGE: ImageOffset for first ICONDIRENTRY should be 0x00000010 * (numbers of removed 256x256 image) backward. So, for example,ImageOffset for first ICONDIRENTRY.(Address: 0x00000012 to 0x00000015 in Ann.bin) Should be 0x00000076 - 0x00000010 * 1 = 0x00000066 instead FOR ICONDIRENTRYs BEFORE THE ONE FOR 256x256 IMAGE: ImageOffset for first ICONDIRENTRY should be 0x00000010 * (numbers of removed 256x256 image) + (sum of bytesInRes of ICONDIRENTRY before the ICONDIRENTRY for the image) backward. So, for example,.0x00006BA3(Address: 0x00000062 to 0x00000065 Ann.bin) should be 0x00006BA3 - 0x00004A65 = 0x0000213E instead 1.when I tried embed an icon containing 256x256 image with mono's resgen and try to run my application, the application crashed. the resgen seems using this method, and this may be the cause. http://go-mono.com/forums/#nabble-td1548909 seems having same problem 2. as a first aid, I wrote private void SaveAll (BinaryWriter writer) { writer.Write (iconDir.idReserved); writer.Write (iconDir.idType); ushort count = iconDir.idCount; writer.Write (count); // himajin100000 modification start //this approach is not using subtraction, just using recalculation. uint offsetsum = 16U * count + 6U; for (int i=0; i < (int)count; i++) { iconDir.idEntries [i].imageOffset = offsetsum; offsetsum = offsetsum + iconDir.idEntries[i].bytesInRes; } // himajin100000 modification end for (int i=0; i < (int)count; i++) { SaveIconDirEntry (writer, iconDir.idEntries [i], UInt32.MaxValue); } for (int i=0; i < (int)count; i++) { SaveIconImage (writer, imageData [i]); } } ,rebuild the System.Drawing.dll and replaced the original System.Drawing.dll in lib\mono\2.0\ and lib\mono\gac\System.Drawing\2.0.0.0__b03f5f7f11d50a3a, cleaned my application not to reuse old Resources.resources,built it, and I was able to run it without crashes. this may be right for a first aid, but I'm 2-1.not sure if I should change the original struct Should I copy the values to local variable and change it? 2-2.not sure if I should do the recalculation not in SaveAll, but in InitFromStreamWithSize. -- Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the QA contact for the bug. You are the assignee for the bug. _______________________________________________ mono-bugs maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-bugs
