Paint.NET v3.5.6 Beta

Every so often an update is necessary to fix 1 bug. This is one of those. Before I describe it, you should head over to the forum and download the beta. I am not making it available via the built-in updater.

The bug in question was reported only recently over on the forum, although I’m pretty sure it’s been in the product since the v3.0 release in early 2007!

It’s classified as a data loss bug, although thankfully it’s a relatively minor one. When Paint.NET starts up, it creates an initial/default image (blank and 800×600) if it wasn’t told to open a specific file. Then, when you eventually/probably open another image it will close that initial/default image as long as it wasn’t modified. The idea is that if you didn’t modify that initial image then you probably don’t care about it, and closing it doesn’t result in any data loss (it’s pretty easy to recreate a blank 800×600 image).

Well, I messed up a little on the implementation of determining whether the image was one that could be automatically discarded. I was only checking the “dirty” bit, which powers the little yellow asterisk you see in the thumbnail list when an image has been modified but not saved. The problem comes with when you modify that initial image, then save it, and then open another image. Paint.NET will incorrectly close that initial image (because the “dirty” bit is set to false) even though you still have items in the history list.

This is especially problematic when you work with a bunch of layers, then save in a format that does not support them (e.g. anything but .PDN). You may want to go back and undo the flatten operation that was performed while saving that image, then make further changes, etc. Inadvertent data loss is the unfortunate result.

And before everyone asks: nothing else is being changed in this release! No new features or tweaks or anything. Those are all being saved for the v4.0 release.

Now, go have a happy Halloween. Please don’t drink too much. I’m personally going out in an astronaut costume, which is pretty awesome.

September 2010 usage statistics – XP no longer on top

The last time I published stats was back in May, and now it’s time for the September edition. The numbers are pretty simple, and the positive trends I reported earlier continue.

Since May, Windows 7’s demographic has increased by 47% (wow!) and now comprises 38% of the user base. 64-bit has shot up by 41% and is now 22.5% of the user base, something that makes me very happy since it was dawdling at <1% for several years. Windows XP is finally below the 50% mark, having dropped to 43%. If you add up Vista and Win7, you get 56.4%, which is very good news. For the first time this means that the majority of Paint.NET users are not on Windows XP! My decision to drop support for XP in the forthcoming v4.0 release (“late 2011,” remember) appears to be a solid business decision, and will let me focus on using newer technologies like Direct2D. Anyone who says “you are dropping support for the majority of your users!!!1” is, well, wrong.


Yay pie charts

  May 2010 September 2010  
Total  hits to update manifest 4,243,221 3,598,716 alt
Hits per day 136,878 116,087 alt
       
32-bit 84.12% 77.53%  
64-bit 15.88% 22.47% alt
       
Windows XP 51.20% 43.42%  
Windows 2003 0.21% 0.18%  
Windows Vista / 2008 22.64% 18.14%  
Windows 7 / 2008 R2 25.95% 38.25% alt
       
English 39.43% 40.33%  
non-English 60.57% 59.67%  
German 15.52% 15.78%  
French 7.99% 7.68%  
Portuguese 5.43% 4.91%  
Spanish 5.78% 5.77%  
Japanese 2.33% 2.46%  
Italian 3.78% 3.77%  
Polish 1.53% 1.39%  
Netherlands (Dutch) 1.37% 1.43%  
Russian 10.31% 10.63%  
Chinese (Simplified) 0.79% 0.66%  
Chinese (Traditional) 0.58% 0.48%  
Turkish 0.95% 0.70%  
Korean 0.32% 0.27%  
All other languages 0.86% 1.02%  
       
Have translations 81.38% 81.62%  
Don’t have translations 18.62% 18.38%  

Paint.NET shows up on Steam’s hardware and software survey

The good folks over at Valve collect and publish statistics about the hardware that their users have installed. For their latest July 2010 stats, they’ve started including installed software.

Some interesting highlights:

  • 56.82% have a dual-core CPU, 26.57% have quad-core, and 0.00% have 24 cores.
  • 100% have Steam installed. (derr)
  • Over 40% are using Windows 7, more than XP or Vista.
  • 5.81% have Paint.NET installed, vs. The GIMP at 6.26%. Not bad for an app that’s 8 years younger with fewer contributors than you can count on 3 fingers.

I’m looking forward to the next update!

Microsoft Ribbon for WPF

I don’t often make “publicity posts” but I know a lot of people have been waiting for this. Microsoft just released the official Ribbon control for WPF (download link). It’s 100% WPF – it isn’t sitting on top of the Windows 7 or MFC Ribbon control, in other words.

This is not the same as what was released about 2 years ago in CTP form. This is brand new, released today. Samples and source code are included!

2474.Office-Word-like-UI-using-WPF-Ribbon[1]
Office Word style UI using Microsoft Ribbon for WPF

Question I know people will ask: “Will you be using this in Paint.NET!?!?!?!”

Pre-emptive answer: Probably not. Paint.NET is based on WinForms, not WPF, and will likely remain that way. Plus, I have other ideas for what to do with the UI in v4. I’m not convinced the Ribbon is what I want to use. If I did use the Microsoft WPF Ribbon (and I’m not saying that I will, remember), I’d have to be very careful since correctly mixing WinForms and WPF can be a bit delicate. Stay tuned of course.

GPU Blur Effects pack for Paint.NET

Bruce Bowyer-Smith has gone to the extraordinary effort to write a pack of GPU-accelerated effects for Paint.NET. It started out with a preview discussion in Plugin Developer’s Central that eventually led to a recent “public” release over in the normal Plugin publishing section.

The pack contains GPU accelerated versions of Gaussian Blur, Motion Blur, Radial Blur, Zoom Blur, as well as a new Channel Blur.

A GPU that supports DirectCompute is required along with Windows 7, or Windows Vista SP2 with the Platform Update (it needs DirectX 11, in other words). Most recent NVIDIA and ATI/AMD cards support this, although Intel’s do not. The latter is a big reason why I have not properly pursued this for Paint.NET yet – there is no high-performance software fallback for DirectCompute. (The “reference driver” does work, but is very slow because it’s intended to render “perfectly” without any regard to performance, and is mostly useful for GPU and driver engineers to make sure they are on the right track.)

It’s interesting to watch these effects execute, because they aren’t any faster on smaller images (and often slower). However, as the size of the image increases, the performance delta becomes very dramatic. The GPU versions just don’t seem to run any slower, while the CPU-based effects quickly lag far behind. These effects are probably hindered by Paint.NETs CPU-centric rendering model, so I wouldn’t be surprised if further performance jumps are possible.

The only downside I’m seeing is that, so far, it is limited to handling images that fit within the maximum texture size that your GPU supports. On a high end video card, that means 8,192 x 8,192 pixels (IIRC).

Paint.NET v4 gets a Settings dialog

I’ve said for a long time that I didn’t want a “Settings” dialog in Paint.NET. I honestly felt that providing as few settings as possible, as well as reasonable defaults for the ones that did exist, was the best way to go.

However, it’s finally to the point where it actually makes sense to consolidate the few settings that Paint.NET has into a proper Settings dialog. This also opens up the ability to easily add new settings where it makes sense.

Here’s a preview:

The “Choose Tool Defaults” dialog will also be folded into this.

I’m using IndirectUI to auto-generate and auto-databind most of this. This is the same system that is used for most of the effect and file type configuration UI as well. It’s a versatile system and is saving me a lot of time. Getting the new application settings system (the data and storage model) up and running has taken a bit of time, but adding any new setting or settings section only takes a few minutes. The dialog here didn’t take much time at all, either.

Effect plugins will be able to query the “Default Quality Level” setting and apply it as they see fit, along with any other settings that end up being pertinent.

Oh, and I’m using DirectWrite to render all of the text now. It works really well, looks great, and is configurable (if you prefer the “GDI Classic” mode, well then just change the setting). Even the buttons are no longer using GDI+, and also have the animations that “real” buttons in the rest of Windows have (this is a change throughout Paint.NET, not just in the Settings dialog).

As usual, the icons are from the excellent Fugue Icon set.

Rotate/Zoom and IndirectUI in Paint.NET v4.0

In my last post I briefly mentioned that Rotate/Zoom had been converted to use IndirectUI. In the current release (v3.5.5) it is implemented with a custom WinForms dialog along with manual data binding, etc. It works fine and simply wasn’t a priority to convert in the v3.5 timeframe.

Well, here’s how it looks now:

It certainly fits in better with the rest of the UI now. The “roll ball 3D” control will also be available for plugins to use. In addition, thanks to some polite prodding by a prominent plugin author (pyrochild), I’ve added the ability to use the regular angle chooser control with a constrained range. Currently, only angle ranges of [-180, +180] and [0, +360] are permitted.

The greyed area shows the angle range that is not permitted.

I’m also planning to add the ability for IndirectUI-based effects and file type UI to use tab pages. This will be useful for having Basic/Advanced pages for file types, and to have more configurable effect properties without resorting to a “tall” UI dialog.

Anyway, that’s all for now!

May 2010 usage statistics – Windows 7 reaches 26%, overtakes Vista

Two months ago I published the usage statistics for March 2010. This month’s data shows a drop in usage for the first time (6.3%), as well as a surprising and unexplained nosedive in the Turkish usage base. I checked the web server’s 404 (“not found”) logs, and it doesn’t account for it, so I’m at a loss to explain it.

In any case, the trends that I’m the most interested in are still showing positive gains. The upward march for Windows 7 (+27.9%!) and 64-bit (+21.1%!) continues, which of course is very good news. Windows 7, at almost 26% total share, has now overtaken Windows Vista, and I’m hoping to see Windows XP fall below the 50% mark soon. I expect that to happen within the next 2 months. The percentages for both English and Russian have gone up, although this may simply be a statistical rebalancing from the mysterious Turkish falloff.

Paint.NET v4.0 is progressing steadily. I’m still in the middle of the “MQ” phase, which is a time for investing in code quality and technology upgrades (“MQ” stands for “Milestone Quality”). I’ve established a good programming model for Direct2D and DirectWrite, improved the super sampling quality for Image->Resize, converted Rotate/Zoom to use IndirectUI, and also significantly improved the way error dialogs and crash logs work.

In previous versions of Paint.NET (which includes the latest v3.5.5), a crash brings a sudden halt to the program with an unfriendly and needlessly verbose dialog:

The user then clicks OK and has no idea what to do about it. This dialog violates the principle of “users don’t read errors” (or anything, honestly, myself included!). Even if they did, it’s unlikely that the crash log would make much sense for them. In Paint.NET v4.0 this will still result in the application shutting down, but at least the UI is improved:

Further improvements may involve hooking into Windows Error Reporting (WER) so that crash logs can be uploaded to me automatically (while respecting your privacy settings, of course).

Clicking on the “Show Details” button will give access to a simple “Copy to clipboard” button and “Open crash log folder” link. The crash logs are no longer unceremoniously (and unprofessionally, I might add) dumped to the desktop. Instead, the last 20 of them are stored in the local (non-roaming) AppData directory (e.g., c:\users\UserName\AppData\Local\Paint.NET\CrashLogs). Most people won’t see that many crashes, of course, but I wanted to ensure these couldn’t gobble up an unbounded amount of disk space. The log files are also stored using NTFS compression to further reduce their disk space impact (although they’re fairly small to begin with).

A similar dialog is also used for reporting other errors. For instance, instead of displaying a nebulous “There was an unspecified error opening the file” error, Paint.NET will now tell you that there was an error (not an “unspecified” error) and let you see the .NET exception. For most situations this won’t really improve the situation, but it will greatly aid troubleshooting – on the forum we can simply ask someone to copy+paste the exception details which will help to speed things up.

Other planned improvements include an “operation restart manager” so that insufficient disk space errors (and others) can be recovered from without data loss, as well as the implementation of a “segmented list” class. The latter will help Paint.NET avoid problems with allocating larger and larger arrays for things like polygon lists (among other things). Instead, the array will be broken up into smaller chunks which a 32-bit system can deal with much more easily.

For instance, if a 200MB array needs to be allocated in a situation where sufficient memory is available but a large enough region of contiguous virtual address space isn’t, this will greatly improve the probability that the allocation will succeed. In fact, often times the problem is that a 150MB (for example) array needs to grow to 200MB, in which case a total of 350MB of memory is required to complete the operation! The SegmentedList<T> class will also avoid the overhead (CPU and memory bandwidth) of constantly copying all those blocks of data, at a cost of higher CPU usage when reading and writing to individual elements within the array. It seems to be a fair tradeoff.

Another improvement coming, one which is long overdue, is fault tolerance when saving an image. Currently, Paint.NET always overwrites the file you are saving and this can have disastrous consequences if an error is encountered in this process. The end result is a 0-byte file even for users who’ve been diligent about saving regularly. The solution is simple, involving first saving to a temporary file and then deleting the old one only when the operation has succeeded. You might ask why this wasn’t implemented a long time ago, and I’ll defer to Raymond Chen’s discussion of the Windows taskbar for an explanation.

The installer now has a hard block on having a minimum amount of memory (RAM). I’m occasionally humored with a crash log from a poor Windows XP user trying to run Paint.NET with 96MB of RAM (which is usually 128MB with a sizable chunk carved out for slow integrated graphics). Sorry, but it just isn’t going to be reliable with so little memory available!

I’ll skip the boring pie charts this month. Here’s the usual tabular data though:

March 2010 May 2010
Total update manifest hits 4,528,824 4,243,221
Hits per day 146,091 136,878
32-bit 86.89% 84.12%
64-bit 13.11% 15.88%
Windows XP 55.76% 51.20%
Windows 2003 0.24% 0.21%
Windows Vista / 2008 23.72% 22.64%
Windows 7 / 2008 R2 20.29% 25.95%
English 38.85% 39.43%
non-English 61.15% 60.57
German 14.68% 15.52%
French 7.79% 7.99%
Portuguese 5.20% 5.43%
Spanish 6.02% 5.78%
Japanese 2.24% 2.33%
Italian 3.57% 3.78%
Polish 1.51% 1.53%
Netherlands (Dutch) 1.35% 1.37%
Russian 9.79% 10.31%
Chinese (Simplified) 0.75% 0.79%
Chinese (Traditional) 0.55% 0.58%
Turkish 3.49% 0.95% ?
Korean 0.35% 0.32%
All other languages 0.81% 0.86%
Have translations 79.45% 81.38%
Don’t have translations 20.55% 18.62%

Bold indicates that Paint.NET ships with the translation. Korean had a translation in v3.36, but not in v3.5+. For Russian, the reverse is true.

Paint.NET v3.5.5 is now available

Here’s the final release for the update to Paint.NET that I’ve been talking about over the last few weeks. It brings performance improvements, a smaller download size, and of course the requisite bug fix. Thanks for everyone who has tried out the Beta and sent in bug reports and installation problems.

As usual, there are two ways to get it. The first is to just go to the Paint.NET website and download it; there is no need to uninstall your older version, as that will be taken care of automatically. The second way is to use the built-in updater. The program will automatically offer you the update within the new week, or you can go to the Utilities menu and click on Check for Updates.

Here’s what’s new since v3.5.4:

  • Fixed the bug where saving as 8-bit PNG/GIF/BMP wasn’t always working, usually with larger images.
  • Improved the performance of the Gaussian Blur effect by 30-40%.
  • Improved the performance of all the layer blending modes by 15-30%.
  • Improved the performance of zooming with the mouse wheel on dual-core Intel Atom systems.
  • Updated to support .NET 4.0 if no other version of .NET is installed.
  • Reduced download size from 4.8MB down to 3.5MB.
  • Fixed a small error in the Chinese translation.

Please note that Service Pack 3 (SP3) is now required for Windows XP users. For those using Windows Vista, you must now have Service Pack 1 (SP1) installed. If you do not have these installed, then the Paint.NET installer will open the appropriate download page on Microsoft’s site.

Enjoy!

Paint.NET v3.5.5 and .NET v4 woes

image The transition to .NET v4 with Paint.NET v3.5.5 has not gone as smoothly as I expected. Right after I released the beta, I immediately started receiving reports of installation problems. Now, before I go into more details, I would like to assure everyone that nothing bad was actually happening. Systems weren’t corrupted, there was no data loss, etc. These weren’t even installation failures, per se; things just weren’t connected seamlessly like they were supposed to be. Clearly it wasn’t ready for prime time.

No, the problem was much more subtle than that and sadly didn’t show up in any of my testing. The reports were along the lines of, “.NET 4 installed and then Paint.NET didn’t do its own update.” If you then tried to run the Paint.NET installer again, nothing would happen: the extractor would run, you’d get a beep, and then nothing. After a reboot, however, you could then run the installer and everything would work great.

As it turns out, on Vista and Win7, .NET 4 first requires an update to some OS components (which it installs automatically). This update, like all other OS updates (e.g., via Windows Update), will not install if a reboot is already pending from another OS update. After that, .NET 4 can install itself. Then the final kicker is that you can’t run a .NET 4-based application until after another reboot. On “Patch Tuesday” it would be very common that TWO reboots would be needed. My installer simply can’t survive across a reboot, nor do I have a desire to implement the code to enable this. I certainly can’t add this code within the timeframe of a 0.0.1 update.

As Liz Lemon on 30 Rock would say, “Nerds!”

image

Let’s just go ahead and get it out of our systems: blah blah blah, reboots suck, what’re those Micro$oft morons* thinking, blah blah blah, Lunix wouldn’t do that because of course it’s perfect, blah blah blah. Now, let’s go back to being adults and just accept that this is the way it works, for better or worse. Please don’t spam the comments box with tirades about reboots. I don’t know why an OS update is necessary, but I sincerely doubt the .NET folks would have done this without a really good reason.

Anyway. This wasn’t the case for .NET 3.5 SP1: even if its installer reported that a reboot was necessary, it was still possible to run the Paint.NET setup wizard (which is a .NET 3.5 SP1 app) and defer the reboot until after everything was completed. More often than not, a reboot was not needed. I think I’ve only seen a reboot needed when installing on XP, mostly when Windows Installer 3.1 also had to be installed.

So, here’s the new plan for Paint.NET v3.5.5. It will not require .NET 4. It will still be based on .NET 3.5 SP1, but with a few important changes to pave the way for a hard dependency on .NET 4. If Paint.NET detects that a reboot is pending from a system update, then it will not auto-check for updates (clicking on Check for Updates will still work as normal). This will help to avoid the confusion when .NET 4 requires a reboot before it can install. I never implemented this before simply because it wasn’t necessary.

I still want to avoid end-user confusion related to .NET’s side-by-side nature. Unlike conventional wisdom might assume, .NET 4 does not include .NET 3.5 SP1 (or 3.0, 2.0, 1.1, and 1.0), which means many people would have installed .NET 4, uninstalled .NET 3.5 SP1 (why would you need it if you have the newer version, after all?), and then hit an error from Paint.NET saying that .NET 3.5 SP1 was required. This is exactly the same problem we had when .NET 2.0 came out and Paint.NET v2.5 still required you to install .NET 1.1. Back then I got more than a few grumpy and indignant e-mails and forum posts from people and calling me bad names because of this. It didn’t even matter that Paint.NET v2.6 was a few weeks away from release at the time.

In order to avoid this confusion, Paint.NET v3.5.5 will support running on a system which has .NET 4 but not .NET 3.5 SP1 installed. However, if both of them are installed then Paint.NET will use .NET 3.5 SP1. This keeps things much simpler for myself and, especially, for plugin authors. If you really do want to run Paint.NET v3.5.5 on top of .NET 4 (and let’s face it, we all want the latest shiny stuff), that will still be possible with a minor tweak to the PaintDotNet.exe.config file: just swap the order of the <supportedRuntime> elements so that the .NET 4 one comes first.

Paint.NET v3.5.5 will still be dropping support for XP SP2 and Vista RTM (pre-SP1). I was planning to do this anyway, as it’s an important stepping stone to phasing out XP support entirely for Paint.NET v4.0. It also helps to shrink the download size by about 700 KB because now I don’t have to include Windows Installer 3.1. Less bandwidth and more simplicity lets me focus on other things that are way cooler.

Going forward, have no fear. It will still be possible for Paint.NET to install .NET 4, then itself, and then not require a reboot until the very end. This involves finessing my setup wizard to target .NET 2.0, something you can always rely on nowadays. Which really isn’t as bad as it sounds; none of my planned changes require anything more than .NET 2.0 and I’d just have to rework some places where I use LINQ or whatever. The setup wizard uses some of the other Paint.NET DLLs but I can just inline that functionality. I’m certainly not rewriting my setup wizard to use WPF or TPL. It’s just something that can’t be done without more code churn and a longer beta testing period.

Expect to see a new beta release shortly.

* I work for Microsoft too, by the way.