示例#1
0
        private void Load(Stream icoStream)
        {
            BinaryReader rdr = new BinaryReader(icoStream);

            IconDirectory dir = new IconDirectory(rdr);

            if (dir.wType == 1)
            {
                Type = IconType.Icon;
            }
            if (dir.wType == 2)
            {
                Type = IconType.Cursor;
            }

            FileIconDirectoryEntry[] subImages = new FileIconDirectoryEntry[dir.wCount];
            for (int i = 0; i < subImages.Length; i++)
            {
                subImages[i] = new FileIconDirectoryEntry(rdr);
            }

            //////////////////////////////////////////

            foreach (FileIconDirectoryEntry entry in subImages)
            {
                rdr.BaseStream.Seek(entry.dwImageOffset, SeekOrigin.Begin);

                Byte[] imageData = rdr.ReadBytes((int)entry.dwBytesInRes);

                IconImage image = new IconImage(imageData, this, entry);
                image.ResourceDataTyped = GetRD(imageData);

                _images.Add(image);
            }
        }
示例#2
0
        private static Byte[] ReconstructRawData(IconDirectory dir, FileIconDirectoryEntry[] ents, IconCursorImageResourceData[] images, ResourceSource source)
        {
            Int32 sizeOfIconDirectory = Marshal.SizeOf(typeof(IconDirectory));
            Int32 sizeOfResIconDirEnt = Marshal.SizeOf(typeof(ResIconDirectoryEntry));

            Int32 sizeOfData =
                sizeOfIconDirectory +
                sizeOfResIconDirEnt * dir.wCount;

            IntPtr p = Marshal.AllocHGlobal(sizeOfData);

            Marshal.StructureToPtr(dir, p, true);

            IntPtr q = Inc(p, Marshal.SizeOf(typeof(IconDirectory)));

            for (int i = 0; i < ents.Length; i++)
            {
                FileIconDirectoryEntry e = ents[i];

                ResourceTypeIdentifier iconImageTypeId = new ResourceTypeIdentifier(new IntPtr((int)Win32ResourceType.IconImage));
                ResourceIdentifier     nameId          = source.GetUnusedName(iconImageTypeId);
                source.Add(iconImageTypeId, nameId, 1033, images[i]);

                ResIconDirectoryEntry d = new ResIconDirectoryEntry()
                {
                    bWidth       = e.bWidth,
                    bHeight      = e.bHeight,
                    bColorCount  = e.bColorCount,
                    bReserved    = e.bReserved,
                    wPlanes      = e.wPlanes,
                    wBitCount    = e.wPlanes,
                    dwBytesInRes = e.dwBytesInRes,
                    wId          = (ushort)images[i].Lang.Name.Identifier.NativeId
                };

                Marshal.StructureToPtr(d, q, true);
                q = Inc(q, sizeOfResIconDirEnt);
            }

            Byte[] data = new Byte[sizeOfData];
            Marshal.Copy(p, data, 0, sizeOfData);

            Marshal.FreeHGlobal(p);

            return(data);

            // Major problem:
            // RawData of a directory contains the ResourceNames of the entries in the ResourceSource
            // seeming as this source does not exist, what should go in their place?

            // idea:
            // when a ResourceData is created from a file it is passed the current ResourceSource which it can 'preliminarily add' the datas to
            //	a UI will need to be presented to prompt the user for details if not in Simple Mode. A UI is presented anyway, so this works.

            // this way the IconCursorImageResourceData has been added to the ResourceSource (with the Action.Add property) and this method can
            //	just query ResourceName. Simple (sort-of)
        }
示例#3
0
        public static void FromFile(Stream stream, UInt16 lang, ResourceSource source, ResIconDir resDir)
        {
            if (stream.Length < Marshal.SizeOf(typeof(IconDirectory)))
            {
                return;
            }

            BinaryReader rdr = new BinaryReader(stream);

            IconDirectory?tDir = ReadIcoHeader(rdr);

            if (tDir == null)
            {
                return;
            }

            IconDirectory dir = tDir.Value;

            ///////////////////////////////
            // rdr is now at the beginning of the array of FileIconDirectoryMembers

            FileIconDirectoryEntry[] subImages = new FileIconDirectoryEntry[dir.wCount];

            for (int i = 0; i < dir.wCount; i++)
            {
                subImages[i] = ReadFileDirMember(rdr);
            }

            /////////////////////////////
            // now for image data itself

            IconImageResourceDataFactory factory = GetIconImageFactory();

            for (int i = 0; i < dir.wCount; i++)
            {
                FileIconDirectoryEntry img = subImages[i];

                stream.Seek(img.dwImageOffset, SeekOrigin.Begin);

                Byte[] data = new Byte[img.dwBytesInRes];

                stream.Read(data, 0, (int)img.dwBytesInRes);

                Size dimensions = new Size(img.bWidth == 0 ? 256 : img.bWidth, img.bHeight == 0 ? 256 : img.bHeight);

                IconCursorImageResourceData memberImageData = factory.FromResource(null, data) as IconCursorImageResourceData;
                IconDirectoryMember         member          = new IconDirectoryMember(memberImageData, dimensions, img.bColorCount, img.bReserved, img.wPlanes, img.wBitCount, img.dwBytesInRes);

                resDir.AddUpdateMemberImage(member);
            }
        }
示例#4
0
        internal IconImage(Byte[] data, IconGroup parentIcon, FileIconDirectoryEntry entry)
        {
            ImageData  = data;
            ParentIcon = parentIcon;

            Size    = new Size(entry.bWidth, entry.bHeight);
            Hotspot = new Point(entry.wXHotspot, entry.wYHotspot);

            ColorCount = entry.bColorCount;
            BitCount   = entry.wBitCount;
            Planes     = entry.wPlanes;

            Validate();
        }
示例#5
0
        public static Boolean TryCreateFromFile(Stream stream, String extension, ResourceSource source, out IconDirectoryResourceData typed)
        {
            typed = null;

            if (extension != "ico")
            {
                throw MEEx(extension);
            }

            if (stream.Length < Marshal.SizeOf(typeof(IconDirectory)))
            {
                return(false);
            }

            BinaryReader rdr = new BinaryReader(stream);

            IconDirectory?tDir = ReadIcoHeader(rdr);

            if (tDir == null)
            {
                return(false);
            }

            IconDirectory dir = tDir.Value;

            ///////////////////////////////

            // rdr is now at the beginning of the array of FileIconDirectoryMembers

            FileIconDirectoryEntry[] subImages = new FileIconDirectoryEntry[dir.wCount];

            for (int i = 0; i < dir.wCount; i++)
            {
                subImages[i] = ReadFileDirMember(rdr);
            }

            /////////////////////////////

            // now for image data itself

            IconImageResourceDataFactory factory = GetIconImageFactory();

            IconCursorImageResourceData[] images = new IconCursorImageResourceData[dir.wCount];
            String[] descs = new String[dir.wCount];

            for (int i = 0; i < dir.wCount; i++)
            {
                FileIconDirectoryEntry img = subImages[i];

                stream.Seek(img.dwImageOffset, SeekOrigin.Begin);

                Byte[] data = new Byte[img.dwBytesInRes];

                stream.Read(data, 0, (int)img.dwBytesInRes);

                images[i] = factory.FromResource(null, data) as IconCursorImageResourceData;

                String description = String.Format(
                    Cult.InvariantCulture,
                    "{0}x{1} {2}-bit",
                    img.bWidth == 0 ? 256 : img.bWidth,
                    img.bHeight == 0 ? 256 : img.bHeight,
                    img.wBitCount
                    );

                descs[i] = description;
            }

            Byte[] reconstructed = ReconstructRawData(dir, subImages, images, source);

            IconDirectoryResourceData retval = new IconDirectoryResourceData(null, reconstructed);

            for (int i = 0; i < images.Length; i++)
            {
                retval.UnderlyingMembers.Add(new IconDirectoryMember(descs[i], images[i]));
            }


            /////////////////////////////

            typed = retval;

            return(true);
        }
示例#6
0
        /// <summary>Saves as an ICO to the specified Stream</summary>
        public void Save(Stream stream)
        {
            BinaryWriter wtr = new BinaryWriter(stream);

            IconDirectory dir = new IconDirectory();

            dir.wReserved = 0;
            dir.wType     = (ushort)(Type == IconType.Icon ? 1u : 2u);
            dir.wCount    = (ushort)_images.Count;

            dir.Write(wtr);

            //////////////////////////////////

            _images.Sort();

            // Calculate offsets

            UInt32 offsetSoFar = (uint)(IconDirectory.Size + _images.Count * FileIconDirectoryEntry.Size);

            UInt32[] offsets = new UInt32[_images.Count];

            for (int i = 0; i < _images.Count; i++)
            {
                offsets[i] = offsetSoFar;

                offsetSoFar += (uint)(_images[i] as IconImage).ImageData.Length;

                if (Type == IconType.Cursor)
                {
                    offsetSoFar -= 4;
                }
            }

            //////////////////////////////////

            for (int i = 0; i < _images.Count; i++)
            {
                IconImage image = _images[i] as IconImage;

                FileIconDirectoryEntry entry = new FileIconDirectoryEntry();
                entry.bWidth  = (byte)image.Size.Width;
                entry.bHeight = (byte)image.Size.Height;

                entry.bColorCount = image.ColorCount;
                entry.bReserved   = 0;

                if (Type == IconType.Icon)
                {
                    entry.wPlanes      = image.Planes;
                    entry.wBitCount    = image.BitCount;
                    entry.dwBytesInRes = (uint)image.ImageData.Length;
                }
                else if (Type == IconType.Cursor)
                {
                    entry.wXHotspot    = (ushort)image.Hotspot.X;
                    entry.wYHotspot    = (ushort)image.Hotspot.Y;
                    entry.dwBytesInRes = (uint)image.ImageData.Length - 4;
                }

                entry.dwImageOffset = offsets[i];

                entry.Write(wtr);
            }

            //////////////////////////////////

            for (int i = 0; i < _images.Count; i++)
            {
                IconImage image = _images[i] as IconImage;

                if (Type == IconType.Icon)
                {
                    wtr.Write(image.ImageData);
                }
                else if (Type == IconType.Cursor)
                {
                    // the first 4 bytes (2 words) of a cursor's image data are discarded

                    wtr.Write(image.ImageData, 4, image.ImageData.Length - 4);
                }
            }
        }