{"id":15662919,"url":"https://github.com/fornever/oddities","last_synced_at":"2025-05-06T02:44:45.506Z","repository":{"id":170760612,"uuid":"646987216","full_name":"ForNeVeR/Oddities","owner":"ForNeVeR","description":".NET libraries supporting several old and obscure data formats: DIB, MRB, NE, SHG, WinHelp.","archived":false,"fork":false,"pushed_at":"2025-04-19T22:43:41.000Z","size":91,"stargazers_count":21,"open_issues_count":6,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-19T23:27:10.664Z","etag":null,"topics":["dib","mrb","ne","shg","winhelp"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ForNeVeR.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-05-29T20:06:14.000Z","updated_at":"2025-03-15T20:35:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"0f6b0156-c2a4-4a5e-b6ab-e6bdfb33dec4","html_url":"https://github.com/ForNeVeR/Oddities","commit_stats":null,"previous_names":["fornever/oddities"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ForNeVeR%2FOddities","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ForNeVeR%2FOddities/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ForNeVeR%2FOddities/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ForNeVeR%2FOddities/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ForNeVeR","download_url":"https://codeload.github.com/ForNeVeR/Oddities/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252612336,"owners_count":21776252,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dib","mrb","ne","shg","winhelp"],"created_at":"2024-10-03T13:34:55.516Z","updated_at":"2025-05-06T02:44:45.488Z","avatar_url":"https://github.com/ForNeVeR.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"Oddities [![Status Ventis][status-ventis]][andivionian-status-classifier]\n========\nThis repository groups several .NET libraries supporting old and obscure data formats.\n\nCurrently, the following data formats are supported:\n- [DIB (Device-Independent Bitmap)][microsoft.dib], encountered as part of the BMP format and in the NE resource table.\n- [NE (New Executable)][wikipedia.ne], 16-bit `.exe` Windows binary.\n- [Windows Help File format][docs.winhelp] (aka WinHelp aka `.hlp`) and accompanying formats (often stored in a `.hlp` file):\n  - [MRB (Multi-Resolution Bitmap)][file-info.mrb],\n  - [SHG (Segmented Hyper-Graphics)][file-info.shg].\n\nIf you encounter a case not handled by the library, don't hesitate to [open an issue][issues]!\n\nRead the corresponding sections below for each part of the library suite.\n\nAll the examples are collected in the `Oddities.Samples` project, feel free to take a look.\n\nDocumentation\n-------------\n- [Contributor Guide][docs.contributing]\n- [License (MIT)][docs.license]\n- [Code of Conduct (adapted from the Contributor Covenant)][docs.code-of-conduct]\n\nOddities.DIB [![NuGet][badge.dib]][nuget.dib]\n------------\nThis library provides some helpful functions to work with the [DIB (Device-Independent Bitmap)][microsoft.dib] image format, often encountered as part of bigger bitmap formats or in resource sections of executable files, such as NE and PE (Portable Executable).\n\nHere's an example of DIB data processing using the library:\n\n```csharp\nbyte[] DibSample(byte[] input)\n{\n    var dib = new Dib(input);\n    var (w, h) = (dib.Width, dib.Height);\n    var (r, g, b) = dib.GetPixel(0, 0);\n    return dib.AsBmp(); // full bitmap data, may be saved to a BMP file\n}\n```\n\n### Known Limitations\n- Only 1, 4, and 8-bit palettes are supported.\n\nOddities.MRB [![NuGet][badge.mrb]][nuget.mrb]\n------------\nThis library supports reading of [MRB (Multi-Resolution Bitmap)][file-info.mrb] and [SHG (Segmented Hyper-Graphics)][file-info.shg] image formats. Most often, these files are encountered during reading of `.HLP` files using Oddities.WilHelp.\n\nThis library has been extracted into a separate package mainly because of different dependencies: it uses a third-party package to read WMF files (that may be part of SHG).\n\nHere's a complex example of how to read an MRB file, extract SHG from it, then extract WMF from SHG, and finally extract a DIB from said SHG (that nesting did actually happen!):\n\n```csharp\nDib ExtractDibFromWmfInsideMrb(string mrbPath)\n{\n    using var stream = new FileStream(mrbPath, FileMode.Open);\n    using var reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);\n    var file = MrbFile.Load(reader);\n    if (file.ImageCount != 1) throw new Exception(\"Too many images in the file\");\n    var image = file.ReadImage(0);\n    WmfDocument wmf = file.ReadWmfDocument(image);\n\n    // Now, for example, let's extract the DIB record from the file, in case the file only stores a single bitmap:\n    var record = wmf.Records.OfType\u003cWmfStretchDIBRecord\u003e().Single();\n    using var dibStream = new MemoryStream();\n    var writer = new BinaryWriter(stream, Encoding.UTF8, leaveOpen: true);\n    record.DIB.Write(writer);\n    return new Dib(dibStream.ToArray());\n}\n```\n\n### Known Limitations\n- Only WMF data is supported inside MRB, no BMP support.\n- Only RLE compression is supported.\n\nOddities.NE [![NuGet][badge.ne]][nuget.ne]\n-----------\nLibrary supporting the [NE (New Executable)][wikipedia.ne] file format (usually stored as `.exe`), the 16-bit executable file format used in Windows 1.0–3.x and some other operating systems.\n\nThe library is currently focused on reading the resource sections of NE files.\n\nSee [Microsoft's documentation on the format][microsoft.ne].\n\nHere's an example function that will read all the resources of type `32770u` from a NE file and wrap every resource into a DIB.\n\n```csharp\nDib[] ReadImagesFromNeFile(string nePath)\n{\n    using var stream = new FileStream(nePath, FileMode.Open, FileAccess.Read);\n    using var reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);\n    var neFile = NeFile.ReadFrom(reader);\n    var resources = neFile.ReadResourceTable();\n    var bitmapResourceType = resources.Single(x =\u003e x.TypeId == 32770u);\n    return bitmapResourceType.Resources\n        .Select(neFile.ReadResourceContent)\n        .Select(x =\u003e new Dib(x))\n        .ToArray();\n}\n```\n\nOddities.WinHelp [![NuGet][badge.winhelp]][nuget.winhelp]\n----------------\nThis library supports reading of Windows Help files, aka WinHelp, aka `.hlp`.\n\nSince the Windows Help format is so complex, only certain features are supported.\n\nHere's what's supported:\n- Reading the Windows Help file's HFS (Hierarchical File System) data and navigating between the files.\n- Reading each HFS entry's raw contents.\n- For `|bm` files, reading them using Oddities.MRB library.\n- For the `|SYSTEM` file, reading and partial validation of the header.\n- For the `|FONT` file, reading of the font descriptors.\n- For the `|TOPIC` file, iterating over the paragraphs and dumping the text records of text paragraphs.\n\nThe following example demonstrates most of the library's capabilities:\n\n```csharp\nvoid DumpWinHelpFile(string hlpPath, string outDir)\n{\n    using var input = new FileStream(hlpPath, FileMode.Open, FileAccess.Read);\n    using var reader = new BinaryReader(input, Encoding.UTF8, leaveOpen: true);\n    var file = WinHelpFile.Load(reader);\n    var dibs = new List\u003cDib\u003e();\n    foreach (var entry in file.GetFiles(Encoding.UTF8))\n    {\n        Console.WriteLine(entry.FileName);\n        var fileName = entry.FileName.Replace(\"|\", \"_\");\n        var outputName = Path.Combine(outDir, fileName);\n        var bytes = file.ReadFile(entry);\n        File.WriteAllBytes(outputName, bytes);\n\n        if (entry.FileName.StartsWith(\"|bm\"))\n        {\n            // Here, you could extract DIB from WMF images, but I'm too lazy to update the signature of\n            // ExtractDibFromWmfInsideMrb to make it work with bytes. Just imagine it works.\n\n            // var dib = ExtractDibFromWmfInsideMrb(bytes);\n            // dibs.Add(dib);\n        }\n        else if (entry.FileName == \"|SYSTEM\")\n        {\n            using var stream = new MemoryStream(bytes);\n            using var headerReader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);\n            var header = SystemHeader.Load(headerReader);\n            Console.WriteLine(\" - SystemHeader ok.\");\n        }\n        else if (entry.FileName == \"|FONT\")\n        {\n            using var stream = new MemoryStream(bytes);\n            using var fontReader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);\n            var fontFile = FontFile.Load(fontReader);\n            Console.WriteLine(\" - Font ok.\");\n\n            foreach (var descriptor in fontFile.ReadDescriptors())\n                Console.WriteLine($\" - - Font descriptor: {descriptor.Attributes}\");\n        }\n        else if (entry.FileName == \"|TOPIC\")\n        {\n            using var stream = new MemoryStream(bytes);\n            using var topicReader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);\n            var topic = TopicFile.Load(topicReader);\n            Console.WriteLine(\" - Topic ok.\");\n\n            var i = 0;\n            foreach (var p in topic.ReadParagraphs())\n            {\n                Console.WriteLine($\" - Paragraph {p} ({p.DataLen1}, {p.DataLen2}) ok.\");\n\n                var out1 = outputName + $\"{i}.1\";\n                Console.WriteLine($\" - - Paragraph data: {out1}\");\n                File.WriteAllBytes(out1, p.ReadData1());\n\n                var out2 = outputName + $\"{i}.2\";\n                Console.WriteLine($\" - - Paragraph data: {out2}\");\n                File.WriteAllBytes(out2, p.ReadData2());\n\n                if (p.RecordType == ParagraphRecordType.TextRecord)\n                {\n                    var items = p.ReadItems(Encoding.GetEncoding(1251));\n                    Console.WriteLine($\"- - Items: {items.Settings}\");\n                    foreach (var item in items.Items)\n                    {\n                        Console.WriteLine($\"- - - {item}\");\n                    }\n                }\n\n                ++i;\n            }\n        }\n    }\n\n    // Also, you may dump dibs here.\n}\n```\n\n### Known Limitations\n- Not supporting any image types other than `0x22` in paragraphs.\n- Not supporting embedded bitmaps (only the external ones that are stored in their own HFS entries).\n\nProject History\n---------------\nThis project started as part of the game reimplementation [O21][o21]. The original game is an old Windows game (from the 3.1 era), and so it was necessary to implement several old Windows data formats to load the game data properly.\n\nSince then, the data format support was extracted into a separate library suite that lives in this repository.\n\nAcknowledgments\n---------------\n- For the documentation on WinHelp, MRB, and SHG, we'd like to thank:\n  - Pete Davis and Mike Wallace, the authors of [Windows Undocumented File Formats][book.windows-undocumented-file-formats],\n  - Manfred Winterhoff, the author of [the documentation][docs.winhelp],\n  - Paul Wise and other contributors of [helpdeco][].\n\n[andivionian-status-classifier]: https://github.com/ForNeVeR/andivionian-status-classifier#status-ventis-\n[badge.dib]: https://img.shields.io/nuget/v/FVNever.Oddities.DIB.svg\n[badge.mrb]: https://img.shields.io/nuget/v/FVNever.Oddities.MRB.svg\n[badge.ne]: https://img.shields.io/nuget/v/FVNever.Oddities.NE.svg\n[badge.winhelp]: https://img.shields.io/nuget/v/FVNever.Oddities.WinHelp.svg\n[book.windows-undocumented-file-formats]: https://a.co/d/dq5fCoj\n[docs.code-of-conduct]: CODE_OF_CONDUCT.md\n[docs.contributing]: CONTRIBUTING.md\n[docs.license]: LICENSE.md\n[docs.winhelp]: http://www.oocities.org/mwinterhoff/helpfile.htm\n[file-info.mrb]: https://fileinfo.com/extension/mrb\n[file-info.shg]: https://fileinfo.com/extension/shg\n[helpdeco]: https://github.com/pmachapman/helpdeco\n[issues]: https://github.com/ForNeVeR/Oddities/issues\n[microsoft.dib]: https://learn.microsoft.com/en-us/windows/win32/gdi/device-independent-bitmaps\n[microsoft.ne]: https://jeffpar.github.io/kbarchive/kb/065/Q65122/\n[nuget.dib]:  https://www.nuget.org/packages/FVNever.Oddities.DIB/\n[nuget.mrb]:  https://www.nuget.org/packages/FVNever.Oddities.MRB/\n[nuget.ne]:  https://www.nuget.org/packages/FVNever.Oddities.NE/\n[nuget.winhelp]:  https://www.nuget.org/packages/FVNever.Oddities.WinHelp/\n[o21]: https://github.com/ForNeVeR/O21\n[status-ventis]: https://img.shields.io/badge/status-ventis-yellow.svg\n[wikipedia.ne]: https://en.wikipedia.org/wiki/New_Executable\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffornever%2Foddities","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffornever%2Foddities","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffornever%2Foddities/lists"}