[Mono-bugs] [Bug 642631] New: System.Drawing.Icon should recalculate the ImageOffset when the specified ico file has 256x256 image.

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Wed Sep 29 12:08:15 EDT 2010


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: mono-bugs at lists.ximian.com
        ReportedBy: himajin100000 at gmail.com
         QAContact: mono-bugs at lists.ximian.com
          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.


More information about the mono-bugs mailing list