Posts Tagged Karl

Posted on Programming

Icon Files: icon creation

So, once I had the system working (upon which I would build the icon maker) I decided ugh I should probably start on the next part. Sure, I was excited to try out my fancy new binary interface, but this pending portion suffered from a drastic decrease in fun and relative increase in tedium.

The logical process went a little something like this:

  1. Read in an image.
  2. Resize it appropriately.
  3. Fill the icon structures with the appropriate data.
  4. Save.

Reading the images was fairly easy, I pretty much just stole the code from bgallery, and modified it with the help of php.net.

One time I took a notebook with me to one of my brother’s roller hockey games. While watching the game I wrote out my magic resize function – which didn’t work. So, I fixed that.

As I extracted image data from the images, processed it, and attempted to force it into the icon structs I encountered a number of bugs. To assist in their eradication, I wrote a few functions for displaying the data which were kind of cool. One of them displayed images as coloured characters, and a later version displayed them as coloured 10×10 divs. Also, I wrote a function called Karl which was way more helpful at squishing bugs.

a processed image

In the end, I had a set of functions that, given an image file, would create an icon resource complete with three 32bit images (48×48, 32×32, 16×16). They preserved transparency in images that supported it, and accepted image formats of JPG, PNG, and GIF.

Since my scripts are set to limit their memory use to 8mb, there are height and width restrictions to the images that can be processed. (width*height*bitcount/8 must be less than 8mb)

 

Posted on Programming

Icon Files: data manipulation

On more than a few occasions over the past nine years, I’ve felt the desire to create an icon. There’ve been many reasons, but each time I’ve felt it deep within my non-existent soul. And each time I was crushed.

Well, maybe not crushed but I could never seem to find a program that would export .ICO files while remaining free. (With the possible exception of pixel editors, but who wants to use those?)

And each time I encountered that problem, I realized that I should just make one. So I did.

C or C++ probably would have been the obvious choice – so I decided to go with PHP. But how to deal with reading binary data at such a low-level, in a good way?

It was this problem that piqued my interest. A low-level binary-data manipulation engine in a high-level scripting language? Well, that sounded both challenging and interesting, if potentially super inefficient. And with something like that, well, an Icon maker should become a good deal simpler to make.

So that’s where it started — with the engine.

There are two types of data in the engine: structures and primitives.

Primitives are things like words, dwords, byte, etc.

$PRIMITIVES = array(
	"WORD" => array("size"=>2, "char"=>"v"),
	"DWORD" => array("size"=>4, "char"=>"V"),
	"LONG" => array("size"=>4, "char"=>"l"),
	"BYTE" => array("size"=>1, "char"=>"C"),
);

Structures are more complex. Structures are made of of fields. Each field in a structure has a type (which can either be another structure, or a primitive) and can have an optional expected value (for rudimentary automated data-checking). Structures are recursively type-checked by the engine, to make sure they resolve to known primitives, before processing.

//http://msdn2.microsoft.com/en-us/library/ms997538.aspx
$ICONDIR = array(  //this one needs its own read function because it has an array
	"idReserved" =>	array("type"=>"WORD", "expected_value"=>0), // Reserved (must be 0)
	"idType" => array("type"=>"WORD", "expected_value"=>1),	// Resource Type (1 for icons)
	"idCount" => array("type"=>"WORD"), // How many images?
	"idEntries" => array("type"=>"ICONDIRENTRY"), // An entry for each image (idCount of them)
);

Of course, one could define a structure recursively – which would be bad – but whatever, let’s ignore that.

The engine takes care of simple loading and storing of functions automatically, but allows you to write your functions if necessary (in the case of structures that contain arrays, for example) and will make use of those if they exist. So you only have to call the default load/store functions, after you define your custom functions.

In cases like ICONDIR, which contains an array whose length is defined by another field in the structure, I had to write a custom load function for it but was not required to write a custom store function (as the general store function handles arrays).

function read_ICONDIR($file_handle) {
	global $ICONDIR, $WARNINGS;
	$out = array();
	foreach($ICONDIR as $k=>$v) {
		if (!in_array($k, array('idEntries'))) {
			$out[$k] = read_structure($file_handle, $v['type']);
			if (array_key_exists('expected_value', $v) and $out[$k] != $v['expected_value']) //basic checking
				$WARNINGS[] = "value read does not match defined expected value: ". "ICONDIR" . "->". $k . ": ". ($out[$k]);
		}
	}
	return $out;
}

So, with karl helping me to track down and fix bugs, I got the engine working.

Coming soon: The icon maker, the interface, and the link! :O