When you view the ‘full view’ version of my article (clicking the ‘comment’ link, or following a full article from off site, there were once two options. My first attempt tried to discern the user’s browser, then forward to an HTML4 friendly page. Otherwise, it sent people to my newer XHTML 1.1 friendly page. Roughly a year ago, I removed the HTML4 friendly page.

It occured to me that it was still difficult to print my page with certain browsers. Most know not to use my CSS markup, however, a few ‘bad’ ones do. This prompted me to create the ‘make printer friendly’ link.

This will render an HTML 2 compatible display of my full article, suitable for printing on everything from Voyager 3 to lynx.

It has also recently come to my attention that a small XHTML error in my ‘site comments’ function was inhibiting Safari 2 users from leaving comments on my site. Oops!

I’ve since fixed it, and tested with Safari 1.3, Opera 8, and Firefox 1.06 (I don’t have Safari 2.0 to test locally, yet) – but I have confirmed that it now works.

All of these functions and additions have been localized for the next release of Rollator; in both Apache mod_rewrite friendly syntax, and with full-encoded URLs (which make it easier for me to develop at home and test – not to mention that some sites still lack mod_rewrite support.)

Wether you use my software, don’t, or just happened to stumble here across this big wide internet, a few dollars will help significantly.

For reference, here’s one report of the Red Cross mismanaging money donated to 9/11:

What’s more, the Savannah chapter “could not provide information regarding cash (and) checks collected.” In Pine Tree, Maine “cash (and) checks (were) unlocked at all times,” and in Los Angeles the chapter there had “no accurate accounting for funds received after Sept. 11,” believed then to total “at least one-half $1 million.”

If that’s not enough, here’s yet another:

...Red Cross officials then closed the Liberty Fund, which had received pledges of $543 million and spent $147 million on September 11 relief efforts—less than one third…

Despite “The Red Cross” having a black eye, I implore you, please consider a donation towards the Katrina Relief Effort. Remember that anything that you can do to help, will.

My build of MKVToolNix is now sync’d to the most recent release, 1.55.

With this release I’ve changed from ‘Stuffit’ to .tar.bz2 for compression. Let me know how easily you manaage to use this form of archive.

You can download this directly from my sofftware page; please choose a mirror site.

When you’re tunneling ports behind NAT, it’s useful to know what ports you have open, and wether or not it’s working. Short of having a system outside of your firewall, there are relatively few safe ways of testing.

There are at least a few sites which offer similar utilities, however, they are usually capable of only testing a single port at a time, which is nearly impossible to use when testing a dynamic range of ports.

For this purpose, I’ve created my TCP port test utility.

Note that I’ve created a few safeguards so this system will not be abused:

  • Only ports between 1024 and 65535 are allowed to be tested.
  • A range of only 50 sequential ports are allowed to be tested at a time.
  • You are only able to test the IP that the server sees you coming from.
  • It uses a simple cookie system; if you block cookies, you won’t be able to use it.

For various reasons, you might find that you wish to find your whole data stream, and post-process it before you send it to the browser. A practical reason is to support ‘Content-Length:’ to increase speed, and cachability of your program, or to manipulate the data again before it’s fully sent to the client. Sometimes, this can be difficult.

For this example, we’ll examine my silly little ‘who are you’ image generator. (Note that this old version does not have features of the new one, but they’re highly semantical (the image buffering and code to display the user’s country, as well as cleaning the code up a bit. I love tenary operators!

In PHP, you want to buffer your content with ob_start().

Here’s a snippit of my local copy’s functioning code: ...
ob_start();
imagejpeg($im);
$imageBuffer = ob_get_contents();
ob_end_clean();
header(‘Last-Modified: ’.gmdate(‘D, d M Y H:i:s’).’ GMT’);
header(‘Content-Length: ’. strlen($imageBuffer));
header(“Content-type: image/jpeg”);
echo(”$imageBuffer”);
imagedestroy($im);

As you see, I tell PHP to begin buffering my output. Then, I tell PHP to create my image with the data stored in $im. I then read that data into a temporary buffer, rather than wasting overhead with a temporary file. I tell it to cleanly end the buffer, and begin the process of displaying my image. I obtain the size of the image, which will be used to specify the length of the image, display it, and cleanly exit.

It is possible (and rather often) for images and other data to be created with no buffering, but then the only trivial solution (I can think of) would be to cause further overhead to obtain the size of our generated image. In this case, it’s not overly necessary, but for a product, as say, a thumbnail generator, I’d strongly suggest buffering, as opposed to creating an interm tempfile.

A sample function for such (say, adding watermarks) might look like:

function waterMark($originalFile, $watermarkFile) { $watermarkSource = imagecreatefromjpeg($watermarkFile); $originalSource = imagecreatefromjpeg($originalFile); ... imagecopymerge($originalSource, $watermarkSource, $originalSourceSizeX, $originalSourceSizeY, 0, 0, $fileWidth, $fileHeight, 100); ob_start(); imagejpeg($originalSource); $imageBuffer = ob_get_contents(); ob_end_clean(); imagedestroy($originalSource); imagedestroy($watermarkSource); return $imageBuffer; }

Thus, you’ll have your watermarked image returned to you as a string; to write out to a file, stuff into an array, or if you’re really sadistic, dumped into a SQL database! :)

Design notes: I chose to set the Last-Modified header as to not cache the image; after all, it is entirely dynamic. I also decided to use ‘echo’ rather than ‘print’ for a rather marginal speed increase, as it does not set a return value.