Friday, January 30th, 2004

Patently idiotic

Both of the following articles describe patents which cover ubiquitous [and self-evident] naming practices.

I would hope that even the non-tech person sees these patents for the steaming piles of bullshit that they are.

IKEA Walkthrough

Friday, January 30th, 2004

A very funny IKEA survival guide, written in the style of a text adventure walkthrough, which probably only 30+ nerds will appreciate:

Upon entering the warehouse, you need to go:

N, N, E, N, S, SW, U, N, W, U, W, W, W, U, NW, N, NW, S, E, W, W, W, N, W.

Now you are in a maze of twisty little passages, all alike. A skeleton, probably the remains of a luckless consumer, lies here.

Some light entertainment, mildly educational

Sunday, January 25th, 2004

That last post was pretty long and might not have been very interesting to 99% of the population of the world. So here’s a bit of fun with bouncing balls, inspired by a friend of mine.

[doesn’t work very well in Netscape/Mozilla browsers… sorry!]

UPDATE: I suspect my Javascript code [specifically the vector maths] is not so efficient, since turning off inter-object collisions results in a performance improvement beyond what I would normally expect. I’m guessing that constantly allocating new objects [vectors] might be taxing the JS engine a bit.

A fine Kludge!

Saturday, January 24th, 2004

It’s not often that a programmer will actually feel pride in a kludge, but right now that’s exactly what I feel, because I just now implemented a kludge that means I can [for now] avoid a few days of work…

1. The Problem

As mentioned not so long ago, I realized to my horror that I had let slide extended character support in HTML Editor. This meant that every time I processed a page that had special symbols on it [e.g. mathematical] the symbols would get replaced with garbage and I would get very annoyed.

2. The Proper Solution

Replace all my ASCII string routines with UTF8 (or WCHAR, or something that supports Unicode anyway) This would take a long time and needs to carefully planned and executed, otherwise a whole bunch of my software will just start falling over. Unfortunately I want this thing to work now

3. The Kludge

Modify just 2 routines and institute a "dynamic code page" system. What this means is that within the same code where I parse and emit entities such as & and > (which mean "&" and "> " respectively) I now also process extended characters and stick them in a dynamically generated lookup table.

For example I might read UTF-8 character 22A1h and store it in table entry 86h. This is useful because now I can replace all instances of the 2 byte character 22A1h with the single byte character 86h. So internally I’m still all 8 bit text. And when it comes time to write the file, the process is reversed, I look up my table with index 86h and get the original value 22A1h, which is what gets written to file.

So basically I am using paletted text! As long as all loading and saving is done via this conversion process, I can forget all my worries!

[another nice thing about using this "palette" methodology is that along with raw character numbers, such as 221Ah or 791h, I can store named entities that I may never have heard of before [such as &rumple; ], treat them as a single character internally and then export them again without ever knowing what they represented]

3a. Things which will come back and bite me on the ass

Of course there are some, and the main one is this: Unicode text requires more than 1 byte per character for a reason… there are more than 256 characters in the world! It’s quite possible to stick more than 256 different characters on a single page, and this kludge can only work when the total number of different characters used [within a program session] does not exceed 256. Once this occurs the lookup table will be full, and new extended characters will be read as invalid (and will show up as ?)

Some sample nasties, which until now were being stomped every time I processed the page as XML:

± ‰ ™ ¥ √ ® µ ÷ ¢ ¶ ½

As I write this, these characters are represented internally [within HTML Editor] as the following high 8 bit characters:

º Â Ã ¾ » Ä ¿ Å Æ Ç À

[translated here using the standard windows code page… will be different from session to session depending on the order in which the extended characters are encoded]

I know what I want for my birthday…

Wednesday, January 21st, 2004

JPL’s home-brewed aerogel [made primarily for catching high speed comet dust] is 99.8% air, and 1000 times less dense than glass!

According to this article, JPL’s aerogel "approaches the density of air." It looks like solid smoke, weighs almost nothing, and is like styrofoam to the touch. It is also 39 times better than fibreglass for thermal insulation.

Apparently this material has been around for decades [not naturally occurring of course] but for some reason I had never heard of it before. If this kind of stuff can be made now, imagine the materials we’ll see as nano-fabrication processes mature [ this article asserts that lighter-than-air aerogels are already possible]

www.fontifier.com

Sunday, January 18th, 2004

( link )

Wednesday, January 14th, 2004

Google is still king

My server logs consistently indicate that Google accounts for the vast majority of search hits on my site, more than 10 times the next in line, Yahoo.

Nerd laughs

Whilst I was vaguely aware of the existence of HomeStarRunner, I had never really delved. This excellent bit, apparently the latest in an ongoing series, makes me suspect I have been missing out!

Conspiracy to hide the true nature of Mars…?

Saturday, January 10th, 2004

… or curiously anomalous image processing… You be the judge!

This entry comprises my description / elaboration of a strange discrepancy pointed out on this page [found via SlashDot], which implies that there is something "dodgy" going on with the images we are getting back from Mars. I don’t know whether this one will do the rounds, but anything involving image manipulation tends to pique my interest, because I think it’s fun to try to reverse engineer the process.

The following are details from images released by Nasa/JPL [I adjusted brightness and scale to make them as similar as possible]:

The first image is from a closeup of the "MarsDial", the second is a detail from a large panoramic shot of the martian surface. Note the difference between the color spots around the dial, especially the blue ones. For some reason in the panoramic shot, the blue has come out as extremely bright red [the blue insulation on the wire has also turned red].

Does this mean that images from Mars are "photoshopped" before they are released to the public? Well of coure they are, for the same reasons regular photos are manipulated [to enhance contrast, to build mosaics etc] but still, it is very very difficult to turn deep blue into bright red just by twiddling with the color balance.

Even if JPL was trying to hide a deep blue Nitrogen/Oxygen atmosphere from us, they could easily do it without causing such an over-the-top color shift. Probably there is a much better explanation for the discrepancy, involving infra-red filters and monochromatic CCDs. It’s possible that the blue material relects an unusual amount of light beyond normal visible light wavelengths.

To get a better idea of whether this might be the case, maybe we should just take a look at the raw images, courtesy JPL/NASA:

Spirit: Panoramic Camera: Sol 005 Spirit: Panoramic Camera: Sol 005 Spirit: Panoramic Camera: Sol 005 Spirit: Panoramic Camera: Sol 005 Spirit: Panoramic Camera: Sol 005 Spirit: Panoramic Camera: Sol 005 Spirit: Panoramic Camera: Sol 005

There are seven different color channels here, and I’m guessing that the very first one is the source for our brighter than bright red, although it clearly doesn’t represent "traditional" red as we see it. A possible explanation for this choice [which I read somewhere] is that the panorama was created by 2 cameras, and since the 2 cameras have only one filter in common [infra-red?], it makes sense to select that common filter when constructing the mosaic [otherwise the pieces will be impossible to match].

Whatever the reason, I do think it would be nice to see Mars images as we would with our own eyes.

__________

UPDATE: the following email from Assoc. Prof. James Bell of the Athena Instrument team at Cornell University is quoted in a post describing pretty much this effect:

…The answer is that the color chips on the sundial have different colors in the near-infrared range of Pancam filters. For example, the blue chip is dark near 600 nm, where humans see red light, but is especially bright at 750 nm, which is used as "red" for many Pancam images. So it appears pink in RGB composites. We chose the pigments for the chips on purpose this way, so they could provide different patterns of brightnesses regardless of which filters we used…

- via SlashDot

And this [pdf] document confirms that of the filters available to the panoramic cameras, only 750nm (near infra-red) is common to both.

[thanks James for link]

Alpha Channels

Saturday, January 10th, 2004

Dealing with alpha channels and compositing images today, and realized 2 things:

  1. Pre-multiplied alpha is not very useful
  2. Compositing onto an image which already has an alpha channel is much more complicated [and expensive] than compositing onto a fully opaque image

1. Pre-Multiplied Alpha

A white pixel is commonly represented by the RGB triplet [255,255,255], where 255 is the maximum value storable within 8 bits.

A 50% transparent white pixel is usually much the same, except with an added alpha component to represent opacity [[255,255,255],128]. (Here 128 means 50% visible, with 0 meaning completely transparent and 255 meaning totally opaque)

That’s the normal way to represent a pixel with an alpha channel.

The other (less normal) way is called pre-multiplied alpha, and this is where the RGB values in an image are altered to reflect their opacity. Using this method a 50% opaque white pixel is represented as [[128,128,128],128] .

The good thing about pre-multiplying is that if the alpha channel is discarded or ignored, the color values will look ok (as long as I want to see my image as it would appear on a black background)

The really bad thing about pre-multiplying is that color resolution is reduced as opacity decreases (assuming we are using 24 bit color). This can be illustrated by examining a reversal process of the sort which might occur in any number of image processing applications.

  1. Starting with a light blue pixel at 100% opacity [[240,240,250],255] .
  2. Reduce it to 1% opacity, resulting in the tuple [[2,2,3],3].
  3. Increase opacity back up to 100%. To do this we have to multiply each component by 255/3, giving us [[170,170,255],255] ,

Note that the final color is very different from the one we started with! This would not have happened if we had just left the color components alone while messing with the alpha.

Related Note: The TGA library I have been using was confusing me, because even though I knew the TGA files I was testing with were definitely NOT premultiplied, I found that after loading a TGA file they suddenly seemed to become so. A bit of digging in the code revealed that for some strange reason the library was assuming that I would actually want my images with pre-multiplied alpha, and so was doing the multiplication for me, after the image was loaded. What’s really unusual here is that it wasn’t even configured as an option, it was just hard-coded as if to say "who the hell wouldn’t want pre-multiplied alpha?"

2. Compositing with Destination Alpha

This was a surprisingly tricky one, which I’ve never needed to do before. Many people will be familiar with the simple method of alpha blending using only source alpha:

Color = ColorSrc * AlphaSrc + ColorDst * (1-AlphaSrc)

This works great as long as your destination pixels have no alpha channel (are already 100% opaque). If you do have destination alpha [and therefore require an alpha result as well] the formula suddenly gets a lot uglier:

Alpha = 1 - (1-AlphaSrc) * (1-AlphaDst)

Color = (ColorSrc*AlphaSrc + ColorDst*AlphaDst*(1-AlphaSrc)) / Alpha

Note the division by Alpha required for the color component! Note also therefore that the special case where Alpha is zero cannot yield a Color value, and must be handled separately in order to avoid a divide-by-zero error. Division is a terrible thing to have to perform on a per pixel basis, and graphics programmers have learned to avoid it wherever possible. In this particular case however, I don’t think it can be avoided without resorting to some method of rough approximation. Please someone correct me if I’ve missed anything here…

CSS Overhaul

Wednesday, January 7th, 2004

I have spent some time changing the way my log is laid out so as to a) avoid the unnecessary use of tables, and b) provide the maximum flexibility for layout changes without the need to change the HTML

Part of the reason for this is pragmatic: This log is getting too big to allow for every page to be rebuilt and uploaded every time I change some minor layout options. This new system will let me change almost anything about the layout, completely from within the style sheet.

I have also added the right hand sidebar,wherein dynamic content will be created via a separate JavaScript file. This means that not only can I change the style across this blog with just one file change, I can also change [some of] the content as well!

If you want to be absolutely amazed at what can be achieved through careful use of style sheets, go visit the CSS Zen Garden… it will knock your socks off ;)

Browser incompatibility…

…is still a problem in this day and age, but I have made every effort to deal with this. One major pain in the butt I encountered was that the width attribute seems to be interpreted differently between IE and Mozilla based browsers. The only way to get it consistent was to make sure that items which use absolute positioning have padding set to zero.

Final word on image libraries

Sunday, January 4th, 2004

This code snippet comes from LibTarga , a C library for reading and writing TGA files:

void* data;
int wdt, hgt;

data = tga_load(szFile, &wdt, &hgt, TGA_TRUECOLOR_32);

And that’s it… that’s how you load a TGA image as a 32 bit bitmap. Again, sorry about the previous whiney post, but isn’t it nice when people anticipate the need for a dead-simple, no-fuss API?

Frikkin image loading, again

Saturday, January 3rd, 2004

So I’m in the middle of this job see, and part of the requirement for this particular job is that I must support a bunch of image formats, including PNG.

Ho ho ho, no problem says I, after all, there are well maintained open source libraries out there, which provide said functionality, so all that will be required is a bit of linking and voila! we will have our PNG support, yes?

Ha!

What… Is… The Frikkin Deal… with LibPNG, and its erroneous assumption that the average programmer should actually give a shit about how PNG files are stored. I don’t, and I don’t see why I should have to. PNG is just one of many image formats I’d like to support, and I’d like to spend less than an hour of my time setting up the code to use the library.

I simply don’t understand why this library [and others like it] don’t let me just do the following:

BITMAP bm;
png_load_file(szfile, &bm);

Is that so much to ask?

__________

UPDATE: I realize now that my initial reaction to LibPNG’s API was perhaps some way short of reasonable. Sorry about that. In the end it took me not too much more than an hour and about 70 lines of code to create a HBITMAP from a PNG file. Still, I would recommend that anyone maintaining such a library try to remember that a lot of lazy programmers like myself will of course be looking for the simplest and quickest way to try out something new, and prominently featuring a couple of high level functions like Load(…) and Save(…), along with a "Quickstart" section in the documentation would make LibPNG a lot easier to warm to. [Thanks Andrew for his level-headed response to my initial hot-headed post]

__________

UPDATE (April 1, 2005): Posted source code to load a PNG into an HBITMAP — let me know if you have any problems with it.