Coder Social home page Coder Social logo

postmeback / 7-refactor-code Goto Github PK

View Code? Open in Web Editor NEW

This project forked from fornever/oddities

0.0 0.0 0.0 80 KB

.NET libraries supporting several old and obscure data formats: DIB, MRB, NE, SHG, WinHelp.

License: MIT License

C# 89.81% F# 8.19% PowerShell 2.00%

7-refactor-code's Introduction

Oddities Status Ventis

This repository groups several .NET libraries supporting old and obscure data formats.

Currently, the following data formats are supported:

If you encounter a case not handled by the library, don't hesitate to open an issue!

Read the corresponding sections below for each part of the library suite.

All the examples are collected in the Oddities.Samples project, feel free to take a look.

Documentation

Oddities.DIB NuGet

This library provides some helpful functions to work with the DIB (Device-Independent Bitmap) image format, often encountered as part of bigger bitmap formats or in resource sections of executable files, such as NE and PE (Portable Executable).

Here's an example of DIB data processing using the library:

byte[] DibSample(byte[] input)
{
    var dib = new Dib(input);
    var (w, h) = (dib.Width, dib.Height);
    var (r, g, b) = dib.GetPixel(0, 0);
    return dib.AsBmp(); // full bitmap data, may be saved to a BMP file
}

Known Limitations

  • Only 1, 4, and 8-bit palettes are supported.

Oddities.MRB NuGet

This library supports reading of MRB (Multi-Resolution Bitmap) and SHG (Segmented Hyper-Graphics) image formats. Most often, these files are encountered during reading of .HLP files using Oddities.WilHelp.

This 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).

Here'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!):

Dib ExtractDibFromWmfInsideMrb(string mrbPath)
{
    using var stream = new FileStream(mrbPath, FileMode.Open);
    using var reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);
    var file = MrbFile.Load(reader);
    if (file.ImageCount != 1) throw new Exception("Too many images in the file");
    var image = file.ReadImage(0);
    WmfDocument wmf = file.ReadWmfDocument(image);

    // Now, for example, let's extract the DIB record from the file, in case the file only stores a single bitmap:
    var record = wmf.Records.OfType<WmfStretchDIBRecord>().Single();
    using var dibStream = new MemoryStream();
    var writer = new BinaryWriter(stream, Encoding.UTF8, leaveOpen: true);
    record.DIB.Write(writer);
    return new Dib(dibStream.ToArray());
}

Known Limitations

  • Only WMF data is supported inside MRB, no BMP support.
  • Only RLE compression is supported.

Oddities.NE NuGet

Library supporting the NE (New Executable) file format (usually stored as .exe), the 16-bit executable file format used in Windows 1.0โ€“3.x and some other operating systems.

The library is currently focused on reading the resource sections of NE files.

See Microsoft's documentation on the format.

Here's an example function that will read all the resources of type 32770u from a NE file and wrap every resource into a DIB.

Dib[] ReadImagesFromNeFile(string nePath)
{
    using var stream = new FileStream(nePath, FileMode.Open, FileAccess.Read);
    using var reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);
    var neFile = NeFile.ReadFrom(reader);
    var resources = neFile.ReadResourceTable();
    var bitmapResourceType = resources.Single(x => x.TypeId == 32770u);
    return bitmapResourceType.Resources
        .Select(neFile.ReadResourceContent)
        .Select(x => new Dib(x))
        .ToArray();
}

Oddities.WinHelp NuGet

This library supports reading of Windows Help files, aka WinHelp, aka .hlp.

Since the Windows Help format is so complex, only certain features are supported.

Here's what's supported:

  • Reading the Windows Help file's HFS (Hierarchical File System) data and navigating between the files.
  • Reading each HFS entry's raw contents.
  • For |bm files, reading them using Oddities.MRB library.
  • For the |SYSTEM file, reading and partial validation of the header.
  • For the |FONT file, reading of the font descriptors.
  • For the |TOPIC file, iterating over the paragraphs and dumping the text records of text paragraphs.

The following example demonstrates most of the library's capabilities:

void DumpWinHelpFile(string hlpPath, string outDir)
{
    using var input = new FileStream(hlpPath, FileMode.Open, FileAccess.Read);
    using var reader = new BinaryReader(input, Encoding.UTF8, leaveOpen: true);
    var file = WinHelpFile.Load(reader);
    var dibs = new List<Dib>();
    foreach (var entry in file.GetFiles(Encoding.UTF8))
    {
        Console.WriteLine(entry.FileName);
        var fileName = entry.FileName.Replace("|", "_");
        var outputName = Path.Combine(outDir, fileName);
        var bytes = file.ReadFile(entry);
        File.WriteAllBytes(outputName, bytes);

        if (entry.FileName.StartsWith("|bm"))
        {
            // Here, you could extract DIB from WMF images, but I'm too lazy to update the signature of
            // ExtractDibFromWmfInsideMrb to make it work with bytes. Just imagine it works.

            // var dib = ExtractDibFromWmfInsideMrb(bytes);
            // dibs.Add(dib);
        }
        else if (entry.FileName == "|SYSTEM")
        {
            using var stream = new MemoryStream(bytes);
            using var headerReader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);
            var header = SystemHeader.Load(headerReader);
            Console.WriteLine(" - SystemHeader ok.");
        }
        else if (entry.FileName == "|FONT")
        {
            using var stream = new MemoryStream(bytes);
            using var fontReader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);
            var fontFile = FontFile.Load(fontReader);
            Console.WriteLine(" - Font ok.");

            foreach (var descriptor in fontFile.ReadDescriptors())
                Console.WriteLine($" - - Font descriptor: {descriptor.Attributes}");
        }
        else if (entry.FileName == "|TOPIC")
        {
            using var stream = new MemoryStream(bytes);
            using var topicReader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);
            var topic = TopicFile.Load(topicReader);
            Console.WriteLine(" - Topic ok.");

            var i = 0;
            foreach (var p in topic.ReadParagraphs())
            {
                Console.WriteLine($" - Paragraph {p} ({p.DataLen1}, {p.DataLen2}) ok.");

                var out1 = outputName + $"{i}.1";
                Console.WriteLine($" - - Paragraph data: {out1}");
                File.WriteAllBytes(out1, p.ReadData1());

                var out2 = outputName + $"{i}.2";
                Console.WriteLine($" - - Paragraph data: {out2}");
                File.WriteAllBytes(out2, p.ReadData2());

                if (p.RecordType == ParagraphRecordType.TextRecord)
                {
                    var items = p.ReadItems(Encoding.GetEncoding(1251));
                    Console.WriteLine($"- - Items: {items.Settings}");
                    foreach (var item in items.Items)
                    {
                        Console.WriteLine($"- - - {item}");
                    }
                }

                ++i;
            }
        }
    }

    // Also, you may dump dibs here.
}

Known Limitations

  • Not supporting any image types other than 0x22 in paragraphs.
  • Not supporting embedded bitmaps (only the external ones that are stored in their own HFS entries).

Project History

This project started as part of the game reimplementation 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.

Since then, the data format support was extracted into a separate library suite that lives in this repository.

Acknowledgments

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.