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); } }
/////////////////////////////////////// private Image GetIconForResourceLang(ResourceLang lang) { ResourceData data = lang.Data; if (data is IconDirectoryResourceData) { IconDirectoryResourceData icoDir = data as IconDirectoryResourceData; IconImage bestMember = icoDir.IconGroup.GetIconForSize(__images.ImageSize); if (bestMember == null) { return(null); } IconCursorImageResourceData rd = (bestMember.ResourceData as IconCursorImageResourceData); return(rd.Image); } else if (data is CursorDirectoryResourceData) { CursorDirectoryResourceData curDir = data as CursorDirectoryResourceData; IconImage bestMember = curDir.IconGroup.GetIconForSize(__images.ImageSize); if (bestMember == null) { return(null); } IconCursorImageResourceData rd = (bestMember.ResourceData as IconCursorImageResourceData); return(rd.Image); } else if (data is IconCursorImageResourceData) { IconCursorImageResourceData icoImg = data as IconCursorImageResourceData; return(icoImg.Image); } else if (data is ImageResourceData) { ImageResourceData imgData = data as ImageResourceData; Size s = __images.ImageSize; Image thumb = GetThumbnailImage(s, imgData.Image); return(thumb); } else { return(null); } }
/// <summary>Associates all of the IconImages in this directory with the ResourceSource by creating IconCursorResourceData instances for each IconImage (with the specified Lang)</summary> public void BindToSource(ResourceSource source, UInt16 langId) { IconCursorImageResourceDataFactory factory = GetImageFactory(); ResourceTypeIdentifier typeId = Type == IconType.Icon ? _iiTypeId : _ciTypeId; foreach (IconImage image in _images) { IconCursorImageResourceData rd = (IconCursorImageResourceData)factory.FromFileData(null, image.ImageData, Type == IconType.Icon); image.ResourceDataTyped = rd; source.Add(typeId, source.GetUnusedName(typeId), langId, rd); } }
private static IconCursorImageResourceData GetDataFromWid(ResourceType type, ResourceLang thisLang, ushort wId) { ResourceName name = null; foreach (ResourceName nom in type.Names) { if (nom.Identifier.IntegerId == wId) { name = nom; break; } } if (name == null) { throw new AnolisException("Directory Subimage name not found"); // this has never happened in the past btw } ResourceLang lang = null; foreach (ResourceLang lan in name.Langs) { if (thisLang.LanguageId == 0) // 0 matches any language, so go with the first { lang = lan; break; } if (lan.LanguageId == thisLang.LanguageId) { lang = lan; break; } // because a ResourceName can have multiple languages associated with it. I'm after the ResourceLang's resource data related to this Directory's lang } if (lang == null) { throw new AnolisException("Directory Subimage language not found"); // this has never happened in the past btw } IconCursorImageResourceData data = lang.Data as IconCursorImageResourceData; return(data); }
private void Load(ResourceLang directoryLang, Byte[] rawData) { this.DirectoryLang = directoryLang; using (MemoryStream ms = new MemoryStream(rawData)) { BinaryReader rdr = new BinaryReader(ms); IconDirectory dir = new IconDirectory(rdr); if (dir.wType == 1) { Type = IconType.Icon; } if (dir.wType == 2) { Type = IconType.Cursor; } ResIconDirectoryEntry[] subImages = new ResIconDirectoryEntry[dir.wCount]; for (int i = 0; i < subImages.Length; i++) { subImages[i] = new ResIconDirectoryEntry(rdr); } ////////////////////////////////////////// foreach (ResIconDirectoryEntry entry in subImages) { IconCursorImageResourceData rdata = GetRD(entry.wId); IconImage image = new IconImage(rdata.RawData, this, entry); image.ResourceDataTyped = rdata; _images.Add(image); } } }
private Boolean ShouldExportData(ResourceData data) { ///////////////////////////////// // Special check for icon subimages IconCursorImageResourceData icdata = data as IconCursorImageResourceData; if (icdata != null && !Options.ExportIcons) { return(false); } ///////////////////////////////// // All visual resources should be exported regardless if (data is DirectoryResourceData) { return(true); } if (data is ImageResourceData) { return(true); } if (data is MediaResourceData) { return(true); } ///////////////////////////////// // If non-visual, check with the options if (!Options.ExportNonVisual) { return(false); } ///////////////////////////////// // Certain commonplace resources might not be exported if (Options.ExportCommonRes) { if (data is VersionResourceData) { return(true); } if (data is SgmlResourceData && data.Lang.Name.Type.Identifier.KnownType == Win32ResourceType.Manifest) { return(true); } if (data.Lang.Name.Type.Identifier.StringId == "MUI") { return(true); } } ///////////////////////////////// // Then check size if (Options.ExportNonVisualSize == -1) { return(true); } return(data.RawData.Length >= Options.ExportNonVisualSize); }
public static ResIconDir FromResource(ResourceLang lang, Byte[] rawBytes) { Int32 sizeOfIconDir = Marshal.SizeOf(typeof(IconDirectory)); Int32 sizeOfDirEntr = Marshal.SizeOf(typeof(ResIconDirectoryEntry)); // the data in here is an ICONDIR structure IntPtr p = Marshal.AllocHGlobal(rawBytes.Length); Marshal.Copy(rawBytes, 0, p, rawBytes.Length); // this could be vastly simplified by correctly marshaling the member array of IconDirectory // but that's a can of worms, I'd rather not IconDirectory dir = (IconDirectory)Marshal.PtrToStructure(p, typeof(IconDirectory)); Marshal.FreeHGlobal(p); if (dir.wType != 1 && dir.wType != 2) { throw new InvalidOperationException("Provided rawData is not an icon or cursor"); } ResIconDirectoryEntry[] subImages = new ResIconDirectoryEntry[dir.wCount]; for (int i = 0; i < dir.wCount; i++) { Int32 byteOffset = sizeOfIconDir + sizeOfDirEntr * i; p = Marshal.AllocHGlobal(sizeOfDirEntr); Marshal.Copy(rawBytes, byteOffset, p, sizeOfDirEntr); ResIconDirectoryEntry img = (ResIconDirectoryEntry)Marshal.PtrToStructure(p, typeof(ResIconDirectoryEntry)); subImages[i] = img; } ResIconDir retval = new ResIconDir(dir.wType == 1, lang.LanguageId, lang.Name.Type.Source); // then we might be able to get the resourcedata for the subimages to include in the directory // find the Icon Image resource type ResourceType imageType = null; Win32ResourceType desired = dir.wType == 1 ? Win32ResourceType.IconImage : Win32ResourceType.CursorImage; foreach (ResourceType type in lang.Name.Type.Source.AllTypes) { if (type.Identifier.KnownType == desired) { imageType = type; break; } } if (imageType != null) { foreach (ResIconDirectoryEntry img in subImages) { IconCursorImageResourceData rd = GetDataFromWid(imageType, lang, img.wId); Size dimensions = new Size(img.bWidth == 0 ? 256 : img.bWidth, img.bHeight == 0 ? 256 : img.bHeight); // cursors might have Height == 0, so it should copy the width rather than being set to 256 retval.Members.Add(new IconDirectoryMember(rd, dimensions, img.bColorCount, img.bReserved, img.wPlanes, img.wBitCount, img.dwBytesInRes)); } } return(retval); }