"Oh, gnome-screensaver, I hate you!" - © Simon Law

Oh, and so do I for breaking working software, like mplayer, because known and working xscreensaver interfaces are simply not supported.

P.S. It feels so great to see people use the Debian Debconf6 pool photo in their Slashdotted presentations :D

Dell Inpiron XPS M1710

Well, now I am a proud owner of a one of the most powerful laptops available under two grand. Core Duo 2.0 Ghz, 2 Gb RAM, 120 Gb HDD, 1900x1200 17" screen and NVidia 7900 GS. I am just loving it. It did come with Windows and lots of ther crap which I removed right away. I did reinstall Windows (XP Media Center) to see how it works (it's been a long time :P) and for some gaming (HL2: Episode One in particular, it's been a long time :P). I also installed Ubuntu Dapper as the primary workspace (as something stable, quick to set up and boringly non-experimental). Debian as the development platform and primary experimentation base and one more 5 Gb partition stayed free so that I can try out other stuff (like Gentoo) when I feel like it.
I must say that installing Ubuntu and Windows in quick succession was a very, very interesting experience. I am considering repeating that and writing down everything with plenty of unusual screenshots to trully compare the experience. I must say that Ubuntu fared the best and Windows being waaay behind on usability and installlability with all kinds of wierdness.
Note: I did not install Debian here yet - university presses to work.

Spot focus

For a long time I have considered F-Spot to be a nice concept application, but not really fit to be the center of Linux digital photography experience due to general bloat and (most importantly) due to the lack of many important features that would compensate the interface lock in that this application demands. In this post I will try to list all the deficiencies and lacking features of F-Spot that I have found while using it to manage my photo flow.
First let's talk about the bloat. I will compare F-Spot to GThumb. There are few points of comparison: first start up, viewing a bunch of photos and importing a bunch of photos. When starting up GThumb uses 17 Mb RSS memory (10 of them shared with all other Gnome programs) while F-Spot uses 33 Mb RSS memory (17 of them shared with other Mono programs, of which I do not have any). When viewing a folder with couple hundred photos GThumb uses 25 Mb RSS memory while F-Spot grows to 55 Mb RSS. On import GThumb calls gphoto that adds 3-5 Mb RSS to the memory usage, while F-Spot seems to implement some/most of the photo protocol internally and can easily grow in memory up to the size of the photos being imported (which is kind of problematic while importing a gigabyte of photos), but usually the memory usage on import hangs around 250-300 Mb and hovers around that level for some time after the import is complete. For me personally it does not make much a difference (I have 2 Gb RAM now), but conservative memory usage is still critical for a good Linux application because people expect Linux to be faster and high memory usage can slow down anything. In my opinion no photo management operation should take more then 50 Mb of private RSS memory (even importing several gigs of RAW files from the camera).
Now let me try to describe the optimal work process of a (semi)professional photographer, so that we can see what is missing in F-Spot to accommodate such work-flow and what is done right.

  1. The photographer takes one (or several) cameras, lenses, flashes, memory cars, spare batteries and tripods and goes to an event/photoshoot/modelling session/walk in the park/wedding/...

  2. He takes 3-5 Gb of pictures from lots of different angles with different cameras, different lenses on different memory cards with different settings. Most of them will be the highest quality available on the camera, usually those will be RAW images.

  3. Upon getting back to his computer, the photographer wants to drop all the data to a staging place dedicated to this event. He wants to do it fast and simple without sorting trough the photos at the moment, but at the same time he might want to split the staging areas (multiple models within one session) or join them (one model from different cameras). Sometimes he might not even have time for that and would just want to dump the data now and run to another event.

  4. After several shooting events the photographer finally has reserved the time to sift trough some of the photos from the staging area (modelling jobs first, then the friends wedding and the walk in the park as last)

  5. First the photographer decides to check if the times on the photographs are correct and discovers that at some shooting sessions one of the cameras was set to another timezone. He select all shots from that camera across several (but not all) staging areas and adjusts the time.

  6. Now he rechecks the logical groups of photos (which photos should be in which staging area) by dragging the photos around, splitting and joining the staging areas

  7. When the overall structure is clear, the photographer selects one (most important) staging area and starts working with images in that staging area not caring about any other images

  8. First he browses in full screen trough all the photos rating them in quality scores form 1 to 9 by pressing corresponding number keys. Rating a picture automatically advances to the next picture, which happens very fast because the software precaches several photos ahead for speed and displays without any flicker. Speeds in the order of 2 photos per second are expected on good enough hardware. One key operations for "view 100% zoom", "rotate", "view exif" and "quick note" are available. RAW images are automatically translated for preview with default settings.

  9. With couple clicks bad photos (with score of 4 or under) are selected and erased

  10. Now the photographer starts working with individual photos

  11. First step is the RAW->Jpeg conversion. An appropriate tool is brought up with default setting already applied and a preview of the photo showing up (like in dcraw). The photographer adjusts the conversion parameters (including and option to make a HDR-like effect by compressing the dynamic range of high bitness pictures). The converted Jpeg is saved as a version of the original photo and becomes the default for operations that do not understand RAW.

  12. A separate plugin is used to reduce digital photo noise from the pictures (new version)

  13. Photographer makes adjustments to the image inside F-Spot. Each modification makes a new version.

  14. Still not satisfied, the photographer starts Gimp from inside F-Spot and make further edits. Each time Gimp saves the file, F-Spot makes another version.

  15. The photographer erases some versions of the picture and also joins multiple near-duplicate shots into one picture as versions of that picture. One version is always marked as the top version and the photographer can easily change it.

  16. The good photos are tagged and imported to the main collection

  17. A subset of the photos is exported to: Flickr, personal Gallery installation, plain html photo album, a zip file with small (1024x...) versions of the photos, ... Only the top versions of photos are exported. If unconverted RAWs are top versions, then they are converted to Jpeg with default settings. In most cases photos are also downsized before export according to the preferences. Highest quality downsizing is used (anti-aliasing) and also additionally small unsharp mask is run on each photo

  18. The photographer does advanced searches and advanced tag selections to select and display or export subsets of his main collection

  19. The photographer has three instances of F-Spot: his laptop, his main work PC and a backup hard drive that can be attached to either of them. He needs to keep his F-Spot photographs synchronised between the three locations for backups and for distributed work. Also after some point the main photo archive becomes too big to store it (with all versions) on the laptop or even on the main PC, so the photographer selects a set of older photos and selects an option to archive them. The next time a connection is established with the backup drive, all versions of archived photos are copied to the backup harddrive and the laptop and the main PC only keep 90% quality Jpeg format picture of the top version of each photo downsized to exactly fit the display resolution of the device. If even that takes too much space then "Archive Only" option is selected which insures that the backup harddrive has the copy of the photo and then erases it from primary data stores completely.

  20. When the backup harddrive is connected it is also very simple to make DVD/HDDVD/Blueray backup copies of subsets of photos from the archive with all the metadata and versions in such a way that other software (and even dedicated media devices) could easily browse the top versions of photos directly from the backup media. Of course, restoring from such backups also must be tested.

So, to summarise, the changes needed for F-Spot are:

  • Support for the concept of staging areas and staging area manipulation

  • Much better performance on import

  • Camera timestamp correction tool (#)

  • Quick rating tool (#)

  • RAW support for controlled conversion and automatic conversion at export (#)

  • Support for external editor with automatic version control and format conversion (#)

  • Noise reduction plugin support (#)

  • Support for version manipulation - join (#, #) and split (#) version stacks

  • Preferences for export methods with resize and quality options and automatic enhancement options at export

  • Multiple instances and data sync (#)

  • Archival support and total archival option

  • Backup (also from archive) support (#, #)

  • More powerful search and filter options (#) with automatic options from exif data (#): People/Mike AND Events/wedding AND (camera/RebelXT OR camera/SonyF717) AND setting/noflash AND lens/wide

As you can see, many of those issues are already reported to F-Spot bugzilla, but have recieved little attention. So what shall we do about it?


From the previous version of my last post, people with even moderate knowledge of English could have easily understood that I suck at spelling and that, consequently, I did not have a spelling checker installed at this blog. Both of those two conclusions would be true.
So I decided to break in and install something to help me and after some mishaps, I settled on Visual Spellcheck plug-in. I am editing my posts in HTML anyway, so lack of WYSIWYG editor support is not critical for me, more like the opposite. All I needed was to install the plug-in, activate it in wordpress, install php5-pspell package and restart Apache. I forgot to restart Apache at first and got a cryptic error from the included fake pspell wrapper. Also aspell and corresponding language libraries must be installed on server site.
Note: after you have corrected all spelling errors in your text you must also remember to press "Continue Editing" link or otherwise changes will not be saved. I think that is a bug.


Speaker break-in time myth or reality tries to debunk the myth of audio speakers needing time in orders of 30-50 hours to get to their best audio properties after purchase.
I bought a new set of Sennheiser HD 215 a few weeks ago. I unpacked them and connected to my laptop. I was blown away by their performance, but something at how the bass frequencies were "muddy" and not clean confused me. Then I read in the manual that I should play some music on the headphones for at least 30 hours to break them in and only then they would get to their best audio characteristics. So I left the headphones on the laptop and left some music playing in them overnight and only came to them after at least 20 more hours of breaking-in. I put the same music on as I did the first time and I was not disappointed - the bass was much more clean and instruments in the bass area were finally as distinct as they should be at this level of headphones. I did not listen to the music during the break-in time, so my brain did not adopt to the sound of these headphones - they actually sounded better.
I do not really care that a distinguished loudspeaker engineer can not find an explanation of how this break-in happens, but that does not change the fact - it exists.
Update - A few more links:

In the end people end up playing sine waves and measuring frequency response thus oversimplifying the problem. It is well possible that non-sinusiodal sound is needed for proper break-in (as in sound with multiple different frequencies at once, or sound with harmonics, ...). It is well possible that the "sharpness" or "muddiness" that is reported by the audiophiles as the characteristic of a non-broken in sound system is not something that is measurable by frequency response - enharmonic dispositions, temporal dispositions and other distortions of the sound are easy to detect by a trained ear, but very hard measure with precision unless targeted. Also people ignore the real complexities of the materials that are used. We think that wood is simple and plain and understood material, but in reality wood is such a superior micro-composite material that it has properties that are still not understood by modern material science. And when we get cooperation of metallic parts, wood, chemicals and, most importantly, natural and complex vibration - predicting all effects of such vibration on the complex system, that is a simple speaker, is ... well ... complex. Audiophile ear can easily hear distortions that normal audio equipment simply can not measure with any confidence.

Discarding phenomena that one simply does not know how to measure or explain is just blindfolding yourself.

I was even more fascinated by the description of an simple non-scientific experiment showing break-in effect on audio cables. This was discarded outright as impossible, but it is actually much easier to understand. Cable is simply a thin piece of metal through which a stream of electrons is flowing. It is not too hard to imagine that these electrons traveling at light speed could impact any impurities or defects in the cable. Any such impacts would distort the analog signal going through the cable. Also after multiple weeks of electron bombardment it is not impossible to imagine such impurities or defects (or the material around them) being changed in a way to ease the flow of electrons (like wind erosion of rocks) thus breaking-in the cables and improving their sound - making it more fluid. That is quite easy to see - why should not there be a set of similar effects working on a whole loudspeaker?


I have just watched a great anime called REC. It is about a male 26 year advertising guy letting a 20 year old girl into his appartment. She aims to become a voice actress for anime, advertising and foreign film voice-overs. They meet accidentaly at the beginning and at the same night her house burns down, so he lets her sleep at his place. But they are not lovers (except for the first night).
The series is quite romantic and soft with bits of humour and just a bit of sexual aspects creeping in just like in the real life. The only problem is that it is short - only 9 episodes. But the ending is good - fitting.
All in all, a good recommendation for a easy viewing but very real romantic anime

Middle-clicking files

A though came to my mind just now - the method of copying text around by just selecting it to copy and using middle-click to paste it. So I wonder, why could one not apply the same for file operations in Nautilus? I would love to just select and middle click to copy files and maybe a Ctrl or Alt key could be used at the paste stage to switch to moving files instead of copying.

Anyone up to the challenge of writing this functionality? Should not be too hard.

For those who care about flamewars!

This MUST stop now! If every DD would express his opinion and anger and frustration on the thread, then it would be the mother of all flamewars and it will suck the life out of all other Debian lists and stop the development outright. Flames shall not pass!

In case someone did not get the joke - it is fun. Join the fun. Display all the traditional flamewar tactics and frases in absurd and hyper overstated ways. Let off some steam in a fictional debate about nothing. Have a bit of fun. It is curiose after all.

Protocol violated

I am offitially screwed. Last night I wanted to reinstall my laptop (which is also my only computer now), so I backuped the contents of my laptop's hard drive to an external usb hard drive as a 13 Gb tar.gz file and happily went on with a format and reinstall.

Of course, when I had completed the installation and went back to unpack files from the backup, I was greeted by a nice message from gunzip - "invalid compressed data--format violated".

Currently I am trying to follow gzip recovery guide that requires one to manually find the next undamaged compression block and make a new gzip file with standart header and then the undamaged compression blocks, but it is quite possible that data after that will also be damaged. Additionally I have no idea how tar will react to me giving it a middle of the archive, hopefully it will not get too confused. Unfortunately the damaged block is only 90 Mb into the 13 Gb file.

Oh, and of course there is a huge heap of really important files that I have no backup for that are on that backup. Fun, fun, fun.

Update: I have managed to recover two crucial OpenOffice.org documents from the formatted filesystem using Magic rescue and now I am proceeding with finding if I can recover anything from the .tar.gz backup file using Gzip recovery toolkit. It is buggy, but it is still better then doing it by hand.

Unfortunately, I also found out about some kind of hardware problem with my external harddrive - if I transfer lots of data to it (think a direct copy of a 13 Gb file), then it just locks up and stops responding until I power cycle it. If I turn off the USB2 support, then it works reliably, but very very slowly. This slows down my recovery attempts even more.

Another blog move

Got access to a new, more powerful server, moved my blog from Mnemosyne to Wordpress, hopefully did not flood p.d.o, did not move the comments over yet.

And not to flood the planet.d.o with the move I did this little change to the Wordpress feed - at the very end of the wp-atom.php file there is this line:

<?php $items_count++; if (($items_count == get_settings('posts_per_rss')) && empty ...

So I changed it to this:

<?php $items_count++; if ((($items_count == get_settings('posts_per_rss')) || $post->post_date < 1150758000 ) && empty ...

Where 1150758000 is the UNIX time of some point between the last post from the old blog and the first post in the new blog.

And I also imported my old posts entries from an Atom feed using the rss feed import as a base. The diff is after the break

--- rss.php 2005-12-28 22:24:12.000000000 +0200
+++ atom.php 2006-06-18 18:26:03.000000000 +0300
@@ -1,13 +1,13 @@
< ?php

-class RSS_Import {
+class Atom_Import {

var $posts = array ();
var $file;

function header() {
echo '<div class="wrap">';
- echo '<h2>'.__('Import RSS').'</h2>';
+ echo '<h2>'.__('Import Atom').'</h2>';

function footer() {
@@ -21,8 +21,8 @@

function greet() {
- echo '<p>'.__('Howdy! This importer allows you to extract posts from any RSS 2.0 file into your blog. This is useful if you want to import your posts from a system that is not handled by a custom import tool. Pick an RSS file to upload and click Import.').'</p>';
- wp_import_upload_form("admin.php?import=rss&step=1");
+ echo '<p>'.__('Howdy! This importer allows you to extract posts from any ATOM 1.0 file into your blog. This is useful if you want to import your posts from a system that is not handled by a custom import tool. Pick an Atom file to upload and click Import.').'</p>';
+ wp_import_upload_form("admin.php?import=atom&step=1");

function get_posts() {
@@ -33,14 +33,14 @@
$importdata = implode('', $datalines); // squish it
$importdata = str_replace(array ("\r\n", "\r"), "\n", $importdata);

- preg_match_all('|<item>(.*?)</item>|is', $importdata, $this->posts);
+ preg_match_all('|<entry>(.*?)</entry>|is', $importdata, $this->posts);
$this->posts = $this->posts[1];
$index = 0;
foreach ($this->posts as $post) {
- preg_match('|<title>(.*?)</title>|is', $post, $post_title);
+ preg_match('|<title [^>]*>(.*?)</title>|is', $post, $post_title);
$post_title = $wpdb->escape(trim($post_title[1]));

- preg_match('|<pubdate>(.*?)</pubdate>|is', $post, $post_date);
+ preg_match('|<published>(.*?)</published>|is', $post, $post_date);

if ($post_date) {
$post_date = strtotime($post_date[1]);
@@ -68,13 +68,13 @@

- preg_match('|<guid .+?>(.*?)</guid>|is', $post, $guid);
+ preg_match('|<id>(.*?)</id>|is', $post, $guid);
if ($guid)
$guid = $wpdb->escape(trim($guid[1]));
$guid = '';

- preg_match('|<content :encoded>(.*?)</content>|is', $post, $post_content);
+ preg_match('|<content [^>]*?>.*?<div .*?>(.*?)</div>\s*?</content>|is', $post, $post_content);
$post_content = str_replace(array ('< ![CDATA[', ']]>'), '', $wpdb->escape(trim($post_content[1])));

if (!$post_content) {
@@ -85,6 +85,7 @@

// Clean up content
$post_content = preg_replace('|< (/?[A-Z]+)|e', "'<' . strtolower('$1')", $post_content);
+ $post_content = str_replace('\n', ' ', $post_content);
$post_content = str_replace('<br>', '<br />', $post_content);
$post_content = str_replace('<hr />', '<hr />', $post_content);

@@ -160,12 +161,12 @@

- function RSS_Import() {
+ function Atom_Import() {
// Nothing.

-$rss_import = new RSS_Import();
+$atom_import = new Atom_Import();

-register_importer('rss', 'RSS', __('Import posts from an RSS feed'), array ($rss_import, 'dispatch'));
+register_importer('atom', 'Atom', __('Import posts from an Atom feed'), array ($atom_import, 'dispatch'));