About a QML Junior Job

Few days ago, we received a bug report about the Plasma calculator widget (plasmoid). Seeing that this bug had also been reported a few months earlier, I wondered how hard it would be to fix it.

The calculator widget is written in QML, a relatively young language, so my experience is rather limited. But playing with QML widgets is very easy: you just need a text editor, change the source, and use the plasma-windowed command to launch the modified plasmoid. No compilation or installing is needed.

So did I fix the bug? Yes and no. Changing some “if’s”, I was able to fix the bug, but playing with the calculator, I noticed a severe regression: If you typed “3+4+5=6+7=” it would first calculate 12, then 25.

To be honest, I was simply too lazy to investigate further. I reverted the changes, and marked the bug as a Junior Job instead. These are bugs that KDE developers believe to be relatively easy to fix. My intention was evil: Someone else should get his hands dirty! And I got rewarded …

A few days later, Paul added a patch to the bug report, fixing it without nasty regressions. After it went through code review at reviewboard.kde.org, it had been committed to the KDE code repositories, and you can see his work starting with the coming 4.11.2 release of our software compilation.

Why am I telling you all this? First, if you are a looking for a way to contribute to KDE projects, the list of junior jobs might be a good start. If you get stuck and need help, check http://techbase.kde.org/Contribute. It contains many links for ways to contact KDE developers.

Second, as the maintainer of KDE software, you should keep an eye on bug reports. If a bug looks easy, do not fix it immediately, but mark it as a junior job instead. This way, you give new contributors a chance to start contributing. Without a list of junior jobs, you will have a much harder time finding help.

And finally, the number of Plasma widgets written in QML is growing. Even if not marked as a junior job, some Plasma bugs can be solved without much coding experience. See this bug for another example.

ImageZero 5x faster than WebP

When the initial preview version of ImageZero (IZ) had been announced, many readers were interested in benchmarks against other compression algorithms, such as JPEG-2000 or Google’s new lossless WebP. At that time, however, the WebP software was not yet ready for testing; it was not possible to benchmark the decompression time, because the software could only convert back to PNG (and PNG encoding is known to be slow), and the compression crashed on large photos.

Luckily, the 0.2 version of the WebP tools has been released, and with this, the Lossless Photo Compression Benchmark has been updated to include results for WebP and ImageZero. Here are the most interesting results:

Software / License Size (% of 3.46 GB) Compression Decompression
uncompressed 100.0%
bzip2 -1 (bzip2 License) 56.3% 476 s 218 s
PNG (libpng License) 42.5% 844 s 72 s
ImageZero (BSD) 41.3% 23 s 21 s
JPEG-LS (HP License) 37.4% 107 s 92 s
lossless WebP (BSD) 35.6% 7525 s 110 s
Flic (proprietary) 30.0% 210 s 231 s
Gralic (proprietary) 28.1% 1734 s 1897 s

Reverse Antialiasing for Image Scaling

When enlarging screen images, for example using screen magnifier utilities such as KDE’s KMag, the antialiasing used for rendering text becomes very visible (see left image). To limit the effect, simple pixel replication is not suited, but a different scaling algorithm needs to be used. The simplest of those algorithms is the bilinear filtering method, which is quite fast, but has the disadvantage of blurring the result.

More advanced methods, such as the Mitchell filter, obtain better results, but are slower to compute and introduce new kinds of artifacts, called ringing. For more information about the kind of artifacts linear scaling methods introduce, please refer to this interpolation introduction.

Image Scaling Comparison

Several methods for non-linear image scaling were proposed, some of them especially fast, some of them optimized for pixel art, others using several megabytes of trained neuronal networks etc. There is always a trade off you have to make between the image quality, and the speed you get.

While the source code for the neuronal network-based scaler is available (as well as the trained data), it was out of scope for a simple screen magnifier, such as KMag. The algorithm should be fast (maybe the speed of a bicubic scaler), and work without additional data, so that it can be used for KMag.

Again, I was not satisfied with the methods that were previously freely available, so I developed my own version of a scaling algorithm. This time it is optimized for scaling antialiased text or rasterized vector graphics, because it effectively reverses the antialiasing process. The quality is certainly not perfect, especially when faced with thin diagonal lines, but I consider it good and fast enough to be useful in KMag. It should also be quite useful as a resolution doubler for high-resolution (“Retina”) displays, and GPU implementations should be simple.

On the right image, you can see my result, using some text and some graphics from the Oxygen team (unscaled image here). To get an impression how it looks as a screen magnifier, here is a screenshot of a Dolphin window (made by Peter Penz), and its resolution doubled version.

A description of the algorithm will follow later. Just be a bit patient, I am still learning TeX 🙂

Fast Lossless Color Image Compression

In the research field of compression, the usual goal is to achieve the best possible compression rate. The best known algorithms, however, are very slow, and sometimes impractical for real-world applications.

When dealing with images, the situation becomes especially worse considering the fact that photo resolutions are ever increasing. Image sizes of 4500×3000 pixels (or more) are not uncommon. Uncompressed, this amounts to 40 megabytes for 24 bits/pixel, and having to wait several seconds for the image to load or save is annoying.

London Bridge (Tower Bridge) : Reflection on the River Thames
Photo by Anirudh Koul at Flickr

JPEG, the de-facto standard for image compression, while still one of the fastest methods available, has one major drawback: it compresses lossy, in other words, whenever the image is saved, some fidelity is lost. For situations where multiple load/save cycles are to be expected, for example in photo manipulation applications, this is inacceptable.

In the recent months, I have been evaluating available lossless image compression algorithms to select one that is fast, but also good in compression efficiency.

Looking at the Lossless Photo Compression Benchmark I was a bit disappointed to find out that PNG, while quite fast in decompression and offering moderate compression rates, is very slow when compressing images.

The JPEG-LS format, being significantly faster at compression compared to PNG, and even offering improved compression rates of about 15%, seemed a good choice at first. It has, however, several drawbacks: Not only is it slower than PNG in decompression, but HP also has a patent on the used context modeling. No-Go.

What does a programmer do, when he is not satisfied with what is available? Right, he re-invents the world, only to make it better: Last week, I released the initial version of ImageZero (iz, pronounced “easy”), a high-performance lossless RGB photo codec.

Being twice as fast as PNG when decompressing (and more than 20 times faster when compressing) it achieves compression ratios that are near or better than PNG for natural photos, sometimes even better than JPEG-LS for very high quality photos. ImageZero is not intended for grayscale or artificial images, but I may improve the algorithms for those image types.

Method File Size Compression Decompression
uncompressed 46380 KB
JLS 14984 KB 6.6 s 7.3 s
PNG 16256 KB 42.4 s 2.4 s
IZ 15496 KB 1.2 s 1.3 s
Results for the full resolution “London Bridge” photo (4507×3512 pixels)

The used algorithm is really easy: the per-pixel compression and decompression is done without any branches (except for a single branch in the bit coder), so that on today’s super scalar CPUs it can be executed very fast.

Possible uses include:
– image/thumbnail databases
– backing store for image processing apps
– future icon format

If you are interested, please help shaping the library API and file format for .iz files. We can use the kde-imaging mailing list for discussion.

Troubleshooting kded4 Bugs

Not just recently, but as long as KDE exists, we are getting bug reports for the KDE process “kded4“. These include:

  • kded4 crashes
  • kded4 leaks memory
  • kded4 eats 100% CPU
  • kded4 <defunct> process

Before I dive into troubleshooting those problems, let me explain what kded4 does and how it works.

Little Demons Everywhere

In the Plasma Workspace there is a widget to show notifications when the battery goes low. But how does the widget know when this happens? It could just check the battery level every couple of seconds, but this would waste CPU cycles. Instead, many ACPI BIOS implementations can trigger hardware interrupts to notify the operating system about the battery state.

Now Plasma could connect to the OS directly, but this would mean it will not run on other operating systems. The solution is a daemon which has OS specific backends. They watch those OS signals and Plasma can connect to the daemon’s interface (usually via D-Bus) to learn about the battery’s health.

Thus a daemon is small process that often just sits there and waits for OS events and triggers simple actions. KDE needs daemons to watch the network, the printer ports, the screen brightness hotkeys, the mounted disks, etc.

With the numbers of daemons we need, but with the very little work they do, it makes sense to use a single process for all of them. The key advantage is less memory usage, and this is exactly what kded4, the KDE daemon process, exploits: To enable the various daemon functionalities, it loads specialized kded modules instead of needing a separate process for each of them.

The Crux of kded4 Bugs

The downside of this approach is that bugs in any of those modules can be fatal for the complete process; in other words, every module must function correctly for kded4 to operate successfully. Which brings us back to the bugs: Some modules still have issues.

Lets say someone reports a problem about growing kded4 memory usage. With the above description in mind, it is easy to understand that – without further analysis – the bug could be in any module, or even in multiple of them. Since the set of modules that developers use might be different than what the reporter used, and the daemons often only handle very seldom actions, many issues cannot be reproduced easily, and without some help from the bug reporter, those problems often cannot be fixed.

The following checklist should guide you through the steps required to troubleshoot kded4 bugs and help collecting information needed to fix them.

Make Sure the Bug is Reproducible

Some bugs only show once. You installed an update, and on next reboot, kded4 crashes, maybe because some configuration files were not correctly updated yet. On subsequent reboots, it works fine without a crash. What to do? Most people do not save previous configuration files, so even when going back to the old version before the update, the crash might never happen again.

You plugged in a headset, and kded4 starts consuming 100% CPU cycles, maybe because a new device triggers a bug in underlying Phonon modules. If you restart, this bug never happens again, because Phonon might “remember” the headset, and not trigger the bug on this code path. Worth a report?

You log out of KDE, noticing you have hundreds of hanging (defunct) kded4 processes lying around. After killing them all and logging in again, there is only a single kded4 process, and that correctly terminates on logout, so you might think the problem was only temporary. The reason is that the process might only hang when a module performs a certain action; it is never the logout per se that makes kded4 hang.

Related are problems that show when kded4 hangs or does not run at all. The symptoms are often completely unrelated. For example, people notice cookies in Konqueror not working, and the usual cause is kded4 not running. Some module might prevent it from starting, or cause it to hang, e.g. waiting for an event that never happens. Of course, these issues should also be fixed.

If you want to report such a bug, make sure you can reproduce it. Try finding old configuration files, try reverting to previous versions, try to find out what steps or actions are required to trigger it. Use the top console command to verify if kde4 really consumes CPU cycles or eats memory. If you cannot reproduce, there is little chance we can. Bugs that never go away are easier, but that does not imply we can see them, too.

Isolate the Offender

The next step is to find out which module is responsible. Without this information, there is often little we can do.

Disable kded4 modules in System Settings > Startup and Shutdown > Service Manager. Some modules cannot be disabled there or automatically start even if you disabled them. To disable such a module, remove its .desktop file from /usr/share/kde4/services/kded/, run kbuildsycoca4, and restart kded4. (Move them to a place where you can easily restore them. This requires root privileges.)

Regularily retrying to reproduce the bug with some modules disabled should eventually lead to the offender. Of course you should start with the “obvious” candidates. For example, if a problem shows when plugging an audio device, the fault is very likely in the phononserver module. For crashes, the offending module can often be found in the complete backtrace.

But sometimes the bug is only triggered by specific combinations of modules, so some patience trying to find them certainly helps. If the problem is reproducible regardless of modules, the bug might really be in kded4 itself, but this is very unlikely from looking at last years bug reports.

Check Existing Bugs

Before filing a new bug report, you should check existing reports for similar or identical problems. If you add a comment with your findings it may be the determining factor for fixing the bug. If you found no similar report, add a new one. Ideally you report it against the module which is responsible.

Note that some distributions might add additional distribution specific modules, in particular to check repositories for software updates. Bugs for those modules should be reported to the bug tracker of your distribution.

In any case, if you are not sure about any of above steps, you might contact KDE forums to ask for help. Even if you cannot provide all required information, it is better to write a report for a new bug, instead of hoping someone else does. Only if you want to see it fixed, of course.

Smaragd adds Emerald window decorations to KDE

Smaragd, the Emerald engine for the KDE window manager KWin, is nearing its first alpha release. While there is still no comfortable theme installation procedure, the engine has seen many improvements compared to the first announcement.

In the latest 0.0.7 version, support for shadows, animations, and button glow has been added. Additionally, many bugs have been fixed, and it should now support all Emerald themes, including those that do not provide its own button pixmaps.

If you want to test Smaragd, make sure you first try without custom button positions enabled in System Settings. Smaragd is then able to use the button positions from the theme and this guarantees best results. If you later would like to swap some buttons, or remove some, then you can enable custom button positions.

To manage your downloaded themes, you can use the following command (if you did not install KDE4 to /usr, then you have to adjust the path):

khotnewstuff4 /usr/share/kde4/config/smaragd.knsrc

This downloads .emerald theme files to the .kde/share/apps/smaragd/themes folder. To select a theme, extract one of those .emerald files to .emerald/theme/ and restart KWin. Make sure you delete any old theme files you had in .emerald/theme/ before you extract a new .emerald file.

Please report bugs or suggestions to http://kde-look.org/content/show.php/Smaragd+(Emerald+for+KDE)?content=125162 or add a comment here.

Sounds on message dialogs

If you run KDE 4.5 from trunk, you should be prepared for some annoyance: I fixed bug 237670, so KDE is now (again) able to play sounds whenever a standard message box appears.

Sounds used to be enabled since ever, but a little bug prevented the messages from triggering any notifications.

If you like the old behavior, disable the sounds using “kcmshell4 notify”, component is “KDE Workspace”, and the actions are all called “Messages”.

The fix is not in KDE 4.5 RC1, but will appear in the second release candidate.

Emerald window decoration themes on KDE

Today I released the initial version of Smaragd, a themable window decoration engine that allows you to use Compiz/Beryl Emerald themes together with the KDE window manager KWin.

This version is not yet ready for production use (there are no shadows and theme installation has to be done manually), but you can already start choosing your favorite theme out of over 1500 available Emerald themes.

For details, see http://kde-look.org/content/show.php/?content=125162

Accelerating color gradients

While looking for ways to improve the KDE color selection dialog, I stumbled upon the slow rendering of the hue/saturation color gradient. Using a simple trick such gradients can be rendered using hardware facilities.

The goal is to render a two-dimensional gradient as depicted below. The current implementation allocates a properly sized QImage, and computes the RGB color values for each individual pixel.

Hue/saturation two-dimensional gradient
Hue/saturation two-dimensional gradient

This requires, however, nearly hundred thousand conversions from HSV to RGB color values, and is the primary cause for the slowness of the dialog.

When looking at the resulting RGB values, you will notice that each row (“scanline”) is actually a one-dimensional linear gradient, so it could be rendered using QLinearGradient.

Looking further, you will also see that there is a linear gradient in each column. Such a gradient is called “bilinear”, but Qt does not offer a two-dimensional QGradient class.

The trick is to create this bilinear gradient by scaling up a very small QImage. The image you see above is actually only 7×2 pixels large. The image is then rendered to a larger QPixmap with scaling applied, so that possible hardware scaling can be used.

A requirement is that pixmap scaling supports bilinear interpolation. This mode, however, is even available with the software scaling algorithms built into Qt.

Improved window themes with deKorator 0.5

If you love to customize the appearance of your KDE Desktop, then you probably already know deKorator, a pixmap window decoration engine initially written by Moty Rahamim for KDE 3.

When I ported it to KDE 4, I did not try to improve it in any way; my first goal was to have it available at all. The only new feature in deKorator 0.4 was support for transparent themes to make use of the ARGB ability of KWin 4.3.

Today, deKorator version 0.5.1 has been released, and it comes packed with a whole lot of new features and bug fixes. I was too lazy to update the ChangeLog file (you can get the svn log from playground/artwork/dekorator, though), but since the changes need to be documented somewhere for theme writers, I decided to write a small “changeblog”.

Improved theme installation and selection

The most often reported bug required a rewrite of the theme selection dialog.

deKorator new theme selection dialog
The new theme selection dialog shows previews of the themes

When you installed a theme and clicked on it in the list, it was not selected as the current theme, but you had to “apply paths” first. The feature to set individual paths has been removed from the dialog; simply clicking on a theme selects the paths automatically (you can still set them in the config file manually).

Improved detection of theme files

Another problem was that installation of themes often failed because of the strict naming requirements. Now the detection is much better, it even detects old deKorator 0.1 themes, and tries to find decoration archives inside the installed archive. Some themes still do not install correctly because of wired bugs in the theme files. For example, there are themes that have the “deco” and “buttons” directories directly in the root of the archive, without any directory for the theme name …

GetHotNewStuff support

For many themes, installation can now be done directly from the KNewStuff interface to the openDesktop.org site “kde-look.org”, where over 150 deKorator themes can be downloaded.

deKorator KNewStuff download dialog
Download and rate deKorator themes using the GHNS dialog

Thanks to improvements in the coming KDE SC 4.5 release, you will even be able to rate themes or upload your own themes. With that, we come to a feature that will be appreciated by theme creators.

Separate images for inactive windows

User “Shirakawasuna” requested a set of different images for buttons on inactive windows, and later suggested to use Emerald compatible button files. This has now be implemented in deKorator 0.5.1.

deKorator buttons image file from Emerald themes
A single image contains all button states
(the chessboard pattern shows transparency)

Inside the “buttons” directory, there are usually the directories “normal”, “hover”, and “press”, but you can now also place a single file for each button type directly inside the “buttons” directory. The file has to be named “buttons<Type>.png”, where <Type> is “Close”, “Max”, “Min”, “Restore”, etc. as before.





Contents of deKorator theme archive “Example-theme.tar.gz”

This file must have six images in a single row, all equally sized. The order is “normal”, “hover”, “press” for active windows, then “normal”, “hover”, “press” for inactive windows. For compatibility, you should keep the old individual button files until the new version has been adopted by users.

Note: When porting Emerald themes, you have to rename the files, e.g. from “buttons.max.png” to “buttonsMax.png”. You might also need to add some transparent padding to get them aligned correctly within the frame, as deKorator always centers images that are smaller than the frame.

Additionally, you can now also supply separate images for the frame of inactive windows.

Example of separate decoration images
deKorator supports separate decoration images for active and inactive windows

Inside the “deco” directory, you can place a directory named “inactive” with the same file layout. You do not need to add all images; those that are not provided are used from the “deco” directory.

Attention! Use this feature with care!

deKorator has been designed to allow the user to colorize active and inactive window frames by using the respective colors from Systemsettings, so do not provide separate images if you just want different colors. It is intended that this feature is used to make graphics for inactive windows less detailed (for example, by removing stripes or other decorations). Check the “Modern System” or “KDE 2” themes to see what I mean.

I hope that these improvements give theme writers more freedom in their design or porting efforts; I am looking forward to new themes, maybe even some with real alpha transparency.

Bug fixes in deKorator 0.5.1

  • Fix borders on maximized windows (requested by user “Shirakawasuna”)
  • Fix resize region with small borders (thanks to “Shirakawasuna” for reporting the issue, clearly seen on his “Dots” theme)
  • Fix “hand” cursor over buttons (requested by “Shirakawasuna”)
  • Fix possible crash with NoBorder option (reported by “Ace2016”, thanks!)
  • Fix large images being cropped instead of scaled (reported/requested by “Shirakawasuna”, clearly seen on his Reluna-Bluetiful port)
  • Fix stuck windows when shading windows with masks (this was first reported by “Thailandian”, and later “greggel” found out how to trigger it. Thanks to both!)
  • Fix spelling mistake for masks (found by “Shirakawasuna”)
  • Fix wrong button image “StickyDownPress” used instead of “StickyPress” (thanks to user “greggel” for reporting)
  • Fix partial transparency on button backgrounds (that bug was unnoticed, because there are no partially transparent themes yet)

If you find anything else that needs to be improved, please use the bugs.kde.org bugtracker.