{"id":16117313,"url":"https://github.com/nickbabcock/pfim","last_synced_at":"2025-10-05T01:52:10.828Z","repository":{"id":45193442,"uuid":"34640016","full_name":"nickbabcock/Pfim","owner":"nickbabcock","description":".NET Standard targa (.tga) and direct draw surface (.dds) image decoder","archived":false,"fork":false,"pushed_at":"2025-03-06T22:27:12.000Z","size":11565,"stargazers_count":118,"open_issues_count":10,"forks_count":19,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-01T07:51:49.584Z","etag":null,"topics":["c-sharp","dds","netstandard","targa"],"latest_commit_sha":null,"homepage":"https://nickbabcock.github.io/Pfim/","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/nickbabcock.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"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}},"created_at":"2015-04-27T01:42:15.000Z","updated_at":"2025-03-25T06:35:49.000Z","dependencies_parsed_at":"2024-01-13T16:26:05.766Z","dependency_job_id":"aad5755a-0843-470e-940b-084060059033","html_url":"https://github.com/nickbabcock/Pfim","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickbabcock%2FPfim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickbabcock%2FPfim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickbabcock%2FPfim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickbabcock%2FPfim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickbabcock","download_url":"https://codeload.github.com/nickbabcock/Pfim/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247809962,"owners_count":20999816,"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":["c-sharp","dds","netstandard","targa"],"created_at":"2024-10-09T20:43:57.009Z","updated_at":"2025-10-05T01:52:05.810Z","avatar_url":"https://github.com/nickbabcock.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg src=\"analysis/pfim-viewer.png?raw=true\"\u003e\n\u003cbr/\u003e\nPfim\n\u003c/h1\u003e\n\n[![CI](https://github.com/nickbabcock/Pfim/actions/workflows/ci.yml/badge.svg)](https://github.com/nickbabcock/Pfim/actions/workflows/ci.yml)\n[![NuGet](https://img.shields.io/nuget/v/Pfim.svg)](https://www.nuget.org/packages/Pfim/)\n\n**Pfim is a .NET Standard 2.0 compatible Targa (tga) and Direct Draw Surface\n(dds) decoding library**\n\nPfim can interoperate with a multitude of environments and libraries.\n\n- [Windows Forms (`Bitmap`)](https://github.com/nickbabcock/Pfim/tree/master/src/Pfim.Viewer.Forms)\n- [WPF (`BitmapSource`)](https://github.com/nickbabcock/Pfim/tree/master/src/Pfim.Viewer)\n- [MonoGame (`Texture2D`)](https://github.com/nickbabcock/Pfim/tree/master/src/Pfim.MonoGame)\n- [Skia (`SKImage`)](https://github.com/nickbabcock/Pfim/tree/master/src/Pfim.Skia) (thus can work in Xamarin.Forms: iOS, android, and UWP)\n- [ImageSharp (`Image`)](https://github.com/nickbabcock/Pfim/tree/master/src/Pfim.ImageSharp)\n- Unity (sample pending)\n- And even hooks to allow GPU decoding (sample pending)\n- And more!\n\nSo no matter if you're targeting Windows, Linux, or Mac -- .NET Core or .NET Framework -- desktop, server, or mobile -- Pfim can fit.\n\nSince Pfim emphasizes on being frontend and backend agnostic some work is entailed to coax it into a displayable form. Check out the listed samples for how to use Pfim in each scenario.\n\n## Installation\n\n[**Install from NuGet**](http://www.nuget.org/packages/Pfim/)\n\n## Usage\n\nBelow is a snippet that will convert a 32bit rgba targa or direct draw surface image into a png using the .NET framework.\n\n```csharp\nusing (var image = Pfimage.FromFile(path))\n{\n    PixelFormat format;\n\n    // Convert from Pfim's backend agnostic image format into GDI+'s image format\n    switch (image.Format)\n    {\n        case ImageFormat.Rgba32:\n            format = PixelFormat.Format32bppArgb;\n            break;\n        default:\n            // see the sample for more details\n            throw new NotImplementedException(); \n    }\n\n    // Pin pfim's data array so that it doesn't get reaped by GC, unnecessary\n    // in this snippet but useful technique if the data was going to be used in\n    // control like a picture box\n    var handle = GCHandle.Alloc(image.Data, GCHandleType.Pinned);\n    try\n    {\n        var data = Marshal.UnsafeAddrOfPinnedArrayElement(image.Data, 0);\n        var bitmap = new Bitmap(image.Width, image.Height, image.Stride, format, data);\n        bitmap.Save(Path.ChangeExtension(path, \".png\"), System.Drawing.Imaging.ImageFormat.Png);\n    }\n    finally\n    {\n        handle.Free();\n    }\n}\n```\n\n## Benchmarks\n\nPfim is fast. Faster than anything benchmarked in C#.\n\nThe contestants:\n\n- Pfim 0.10.0\n- [DevIL](http://openil.sourceforge.net/) 0.2.19\n- [FreeImage](http://freeimage.sourceforge.net/) 4.3.6\n- [ImageMagick](https://www.imagemagick.org/script/index.php) 7.12.0\n- [TargaImage](https://www.codeproject.com/Articles/31702/NET-Targa-Image-Reader) 1.0\n- [ImageFormats](https://github.com/dbrant/imageformats) 1.0\n- [StbSharp](https://github.com/rds1983/StbSharp) 0.7.2.38\n- [TgaSharpLib](https://github.com/ALEXGREENALEX/TGASharpLib) 1.0\n\nThe task: a 120x120 image was encoded into 7 different images:  3 different\ntypes of targa and 4 different direct draw surface images. The benchmark was\nhow how many times a library could decode the image.\n\n![](analysis/decode-per-second.png?raw=true)\n\nTakeaways:\n\n- Pfim is hands down the fastest targa decoder. More than 10x faster than the closest competitor\n- For DDS it's a little less clear except for 32bit (uncompressed) images.\n\nRest assured, Pfim is one of the fastest if not the fastest when it comes to\nDDS decoding, but to get a clear view, let's look at the raw data.\n\n![](analysis/median-decode.png?raw=true)\n\nSame story, but it's now apparent that the only time Pfim doesn't come in first is when it was 1% slower for decoding dxt5 DDS images.\n\n## Configuration\n\nThe decoding process can be customized via the `PfimConfig` parameter.\n\n### Buffer Size\n\nWhen reading from a file or stream, this is the buffer size that Pfim will read in chunks of. The default value is 32KiB (kibibytes).\n\n### Decompress\n\nDictate if block encoded direct draw surface areas should be decompressed.\nDefault is true. The only time this should be false is if only the dds metadata\nis desired or decoding will happen on the GPU.\n\n### Allocator\n\nUnless this option is specified, all image allocations are performed via `new\nbyte[]`. This can have less than desired effects on memory usage and GC\nespecially when many images are being decoded. To fix this issue, Pfim\nintroduced an `IImageAllocator` to allow a custom allocation. Below is a naive\nexample for buffer pooling backed by `ArrayPool`\n\n```csharp\nclass PooledAllocator : IImageAllocator\n{\n    private readonly ArrayPool\u003cbyte\u003e _shared = ArrayPool\u003cbyte\u003e.Shared;\n\n    public byte[] Rent(int size)\n    {\n        return _shared.Rent(size);\n    }\n\n    public void Return(byte[] data)\n    {\n        _shared.Return(data);\n    }\n}\n```\n\n### Apply Color Map\n\nSome targa images are mapped such that 24bit pixel data is encoded as 8 bits.\nApplying a color map will make the conversion from 8bit to 24bit. The default\nis true.\n\n### Target Format\n\nReserved for future usage to dictate decode process. For instance instead of\nhaving a post process stage of flipping the red and blue channels, to flip them\nduring the decoding process so only a single pass is needed.\n\n## Contributing\n\nAll contributions are welcome. Here is a quick guideline:\n\n- Does your image fail to parse or look incorrect? File an issue with the image attached.\n- Want Pfim to support more image codecs? Raise an issue to let everyone know you're working on it and then get to work!\n- Have a performance improvement for Pfim? Excellent, run the before and after benchmarks!\n\n```\ndotnet run -c Release --project .\\src\\Pfim.Benchmarks -- --filter '*.Pfim'\n```\n- Know a library to include in the benchmarks? If it is NuGet installable / easily integratable, please raise an issue or pull request!\n\n## Developer Resources\n\nBuilding the library is as easy as\n\n```\ndotnet test -f net6.0\n```\n\nOr hit \"Build\" in Visual Studio :smile:\n\nSome references:\n\n- [Targa image specification](http://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf)\n- [Block compression](https://msdn.microsoft.com/en-us/library/bb694531(v=vs.85).aspx) (useful for dds)\n- [DXT Compression Explained](http://www.fsdeveloper.com/wiki/index.php?title=DXT_compression_explained)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickbabcock%2Fpfim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickbabcock%2Fpfim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickbabcock%2Fpfim/lists"}