I’m Baaaa-aaaack…
Wow, It’s been almost a year since I first finished the core of MagicScaler and wrote my first post here introducing it. I said at the time that I’d be releasing it to Nuget soon, and I’m pretty sure ‘soon’ has come and gone. I got involved in a couple of big projects not long after that, and I haven’t had much time to dedicate to making MagicScaler ready for public consumption. Or any time, really. But I’m back now, and I’ll be making a real effort to get it released soon. For real this time.
In the meantime, some very interesting things have happened. I’ll run down a few of them.
Windows 10 Got Itself Released
And it has some nice Improvements to WIC baked in. Chief among these is an actual high-quality image scaler, which was notably absent in previous versions, prompting me to write my own. Having seen the new scaler in action, I’m pleased to say that writing my own was not a waste of time. That was a legitimate fear I had when I learned about the new features. On the contrary, while the new WICBitmapInterpolationModeHighQualityCubic (that’s a mouthful) is indeed high-quality and fast, it’s still not as good as MagicScaler. It’s a nice tool to have in the arsenal, though, and I may be able to make some improvements to my processing pipeline by leveraging it in some cases.
MagicScaler Didn’t Kill Anybody
I’ve been running MagicScaler on a few production sites for over a year now, and it’s been rock-solid. If there’s one good thing I can take out of my long hiatus from this project, it’s that I got a lot of testing done and served up millions of trouble-free images.
RyuJIT!
.NET 4.6 also got released, and with it came the new (and awesome) RyuJIT compiler. When I wrote the MagicScaler core code, I had to resort to some tricks to get the old x64 JIT compiler to produce performant machine code. I didn’t have to do anything sketchy, just careful ordering of code, scoping of variables, and unrolling of loops to basically back my way into good machine code. I had it humming along quite nicely. Then I ran it against RyuJIT, and I got an extra ~10% performance bonus. That is truly amazing, so my hat’s off to the RyuJIT team.
Along with the new JIT that gave me (and probably many of you) a free performance boost, Microsoft also released the first incarnation of System.Numerics.Vectors, allowing us to write true SIMD code in C#. There are already a few places I can think of where MagicScaler would benefit from such a thing, and I can’t wait to see what kind of extra performance that allows.
.NET Core Got Closer
First it got a new name (thank science!), and then it got a Release Candidate. I’m kind of torn on what that means for this project. While a world of totally open source, platform-independent .NET is definitely exciting, the cost of platform independence is the loss of technologies like WIC (and even GDI+) that are Windows-specific. Having worked with the WIC model for a while now, I’ve really come to appreciate the way it’s designed, both for extensibility and raw performance. I’ll be thinking about how I can possibly replicate that type of pipeline in a post-WIC world if this project gets some momentum behind it.
The good news is, I’ve had great success swapping out broken WIC components for my own (like the scaler) or adding functionality that’s missing from WIC (like matting/layer composition). And I’ve done it all in C#. So technically, it’s likely possible to replace all of it.
The bad news is that WIC does so much and does it so well that replacing all of it is a daunting task. At a minimum, a platform-independent WIC replacement would need encoders, decoders, pixel format converters, and color management. Those are doable, but getting WIC-like performance from a managed platform will be tough.
MagicScaler Got Some Unexpected Competition
I did an early post comparing my reference GDI+ resizer with the most popular such library I could find on Nuget in order to show the effect of GDI+ settings on resizing performance. What I didn’t see at the time was that the author(s) of that library (called ImageResizer) was/were also working on a high-performance replacement for System.Drawing’s DrawImage(). A new version of ImageResizer has already been released, and it includes a component called ‘FastScaling’ that promises to deliver the same kind of performance and quality I built MagicScaler to achieve. I thought I only had to beat GDI+, but now there is another. I’ll be grabbing a copy of that shortly to put it to the test. I love a good competition.