Archive for July, 2010

Forclaz

Friday, July 30th, 2010

Dit jaar zijn m’n liefje en ik naar Annecy gegaan op vakantie. Nu ja, we houden niet zo van de drukte, dus we hebben de campings direct aan het meer (wat zeer mooi is, dat moet gezegd) links laten liggen. We kwamen op een rustieke (na het schijnt) camping terecht nabij Alex.

Na wat verkenningen en een flinke tocht samen, stond op 30 juli de Col de la Forclaz op het programma.


Aangezien deze col meerdere langere stukjes boven de 14 procent kent, zag liefje het niet zitten (Als je de 800 meter daling uit de klim haalt kom je op gemiddeld 8,7 procent, anders is het gemiddeld 8,0 procent).  Wel stond ze met de oto en camara in de aanslag langs de weg (waarvoor heel veel dank):

Filmpje: Soepel de Forclaz op

In 38 minuten boven. Nét geen veertien kilometer per uur. Best aardig al zeg ik het zelf. Onderweg vijf mensen ingehaald, waaronder een Fries te voet. Je merkt dan toch dat dit geen overbekende klim is: het ziet er niet zwart van de wielrenners.

Daarna parkeerden we de oto bij het meer, en reden samen ook nog een leuk rondje met een stevige col. We kwamen heelhuids boven. Naar beneden bleek wat lastiger:

Gelukkig hadden ze allemaal een bel.

Windows multi icon

Friday, July 23rd, 2010

Creating a Windows icon containing multiple bitmaps is not supported by .NET. Fortunately, on the net (the other one) I found a (version 1.1) .NET implementation to read a multi icon.

The re-usability wasn’t that great, merging and writing was not supported, and as .NET 1.1 did not support Typed lists yet, I had to rewrite it all:

using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;

namespace HelloWorld.Drawing
{
	/// <summary>Represents a Windows multi icon, which is a collection of small bitmap images
	/// used to represent an object. Icons can be thought of as transparent
	/// bitmaps, although their size is determined by the system.
	/// </summary>
	public class MultiIcon : List<Icon>
	{
		/// <summary>Initializes a new instance of the Tjip.Drawing.MultiIcon class.</summary>
		public MultiIcon() { }

		/// <summary>Represents the Widows multi icon as System.String.</summary>
		public override string ToString()
		{
			var str = string.Format("{0} Items: {1}",
				GetType().FullName,
				this.Count);
			if (this.Count == 1)
			{
				str += string.Format(", Size: {0} px",
					this.First().Width);
			}
			if (this.Count > 1)
			{
				str += string.Format(", Smallest: {0} px, Largest: {1} px",
					this.GetSmallest().Width,
					this.GetLargest().Width);
			}
			return str;
		}

		/// <summary>Loads a Windows multi icon based on the specfied path.</summary>
		/// <param name="filepath">The filepath to load from.</param>
		public static MultiIcon Load(string filepath)
		{
			using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read))
			{
				return Load(stream);
			}
		}
		/// <summary>Loads a Windows multi icon from a stream.</summary>
		/// <param name="stream">The stream to load from.</param>
		public static MultiIcon Load(Stream stream)
		{
			// Read the stream.
			using (var reader = new BinaryReader(stream))
			{
				var icon = new MultiIcon();
				var entries = new List<MultiIconEntry>();

				// Read the header.
				var header = reader.ReadMultiIconHeader();

				// Read the icon entries.
				for (int i = 0; i < header.Count; i++)
				{
					var entry = reader.ReadMultiIconEntry();
					entries.Add(entry);
				}
				// Read the icons based on the entries.
				foreach (var entry in entries)
				{
					var ico = reader.ReadIcon(header, entry);
					icon.Add(ico);
				}
				return icon;
			}
		}
	}

	/// <summary>Methods for Windows multi icon, that should be available
	/// for all collections of Widows icons.</summary>
	public static class MultiIconExtensions
	{
		/// <summary>Saves the Windows icons to a single file.</summary>
		/// <param name="icon">The list of icons.</param>
		/// <param name="filepath">The filepath to save to.</param>
		public static void Save(this IList<Icon> icons, string filepath)
		{
			using (var stream = new FileStream(filepath, FileMode.CreateNew, FileAccess.Write))
			{
				icons.Save(stream);
			}
		}
		/// <summary>Saves the Windows icons to a single stream.</summary>
		/// <param name="icon">The list of icons.</param>
		/// <param name="stream">The stream to save to.</param>
		public static void Save(this IList<Icon> icons, Stream stream)
		{
			using (var writer = new BinaryWriter(stream))
			{
				long startposition = stream.Position;

				var entries = new List<MultiIconEntry>();
				var buffers = new List<byte[]>();
				// create header.
				var header = new MultiIconHeader()
				{
					Count = (short)icons.Count,
				};
				// create entries.
				for (int i = 0; i < icons.Count; i++)
				{
					using (var icon_stream = new MemoryStream())
					{
						var entry = new MultiIconEntry();
						var item = icons[i];
						item.Save(icon_stream);
						icon_stream.Position = 0;

						using (var reader = new BinaryReader(icon_stream))
						{
							// icoHeader.Reserved[2],
							// icoHeader.Type[2],
							// none.Pos[2],
							// Width[1],
							// Height[1],
							// ColorCount[1],
							// Reserved[1]
							// Planes[2]
							// BitCount[2]
							// BytesInRes[4]
							// none.OffSet[4]
							var header_reserved = reader.ReadInt16();
							var header_type = reader.ReadInt16();
							var none_startpos = reader.ReadInt16();
							entry.Width = reader.ReadByte();
							entry.Height = reader.ReadByte();
							entry.ColorCount = reader.ReadByte();
							entry.Reserved = reader.ReadByte();
							entry.Planes = reader.ReadInt16();
							entry.BitCount = reader.ReadInt16();
							entry.BytesInRes = reader.ReadInt32();
							entry.ImageOffset = MultiIconHeader.ByteSize + MultiIconEntry.ByteSize * icons.Count + buffers.Sum(buf => buf.Length);
							var none_offset = reader.ReadInt32();

							var buffer = new byte[icon_stream.Length - icon_stream.Position];
							icon_stream.Read(buffer, 0, buffer.Length);
							entries.Add(entry);
							buffers.Add(buffer);
						}
					}
				}
				// Writer header.
				writer.Write(header);

				// Write entries.
				foreach (var entry in entries)
				{
					writer.Write(entry);
				}
				// Write images.
				foreach (var buffer in buffers)
				{
					writer.Write(buffer);
				}
				// Clear buffer and save.
				writer.Flush();
			}
		}

		/// <summary>Gets the smallest icon.</summary>
		/// <param name="icon">The list of icons.</param>
		/// <returns>The smallest icon.</returns>
		public static Icon GetSmallest(this IEnumerable<Icon> icons)
		{
			var icon =
			(
				from
					item in icons
				orderby
					item.Width ascending
				select
					item
			)
			.FirstOrDefault();

			return icon;
		}
		/// <summary>Gets the largest icon.</summary>
		/// <param name="icon">The list of icons.</param>
		/// <returns>The largest icon.</returns>
		public static Icon GetLargest(this IEnumerable<Icon> icons)
		{
			var icon =
			(
				from
					item in icons
				orderby
					item.Width descending
				select
					item
			)
			.FirstOrDefault();

			return icon;
		}
	}
	/// <summary>Represents the header of a Windows (multi) icon.</summary>
	internal class MultiIconHeader
	{
		/// <summary>The byte size of a single icon header.</summary>
		public const int ByteSize = 2 + 2 + 2;

		/// <summary>Initializes a new instance of the Tjip.Drawing.MultiIconHeader class.</summary>
		public MultiIconHeader()
		{
			this.Type = 1;
		}

		public short Reserved { get; set; }
		public short Type { get; set; }
		public short Count { get; set; }
	}

	/// <summary>Extension methods for MultiIconHeader.</summary>
	internal static class MultiIconHeaderExtensions
	{
		/// <summary>Reads a Windows (multi) icon header from the current stream
		/// and advances the current position of the stream by six bytes.
		/// </summary>
		/// <param name="reader">The reader.</param>
		public static MultiIconHeader ReadMultiIconHeader(this BinaryReader reader)
		{
			var header = new MultiIconHeader()
			{
				Reserved = reader.ReadInt16(),
				Type = reader.ReadInt16(),
				Count = reader.ReadInt16(),
			};
			return header;
		}

		/// <summary>Writes a Windows (multi) icon header to the current stream
		/// and advances the current position of the stream by six bytes.
		/// </summary>
		/// <param name="writer">The writer.</param>
		/// <param name="header">The Windows multi icon header to write.</param>
		public static void Write(this BinaryWriter writer, MultiIconHeader header)
		{
			writer.Write(header.Reserved);
			writer.Write(header.Type);
			writer.Write(header.Count);
		}
	}
	/// <summary>Represents the entry of a Windows (multi) icon.</summary>
	internal class MultiIconEntry
	{
		/// <summary>The byte size of a single icon entry.</summary>
		public const int ByteSize = 1 + 1 + 1 + 1 + 2 + 2 + 4 + 4;

		/// <summary>Initializes a new instance of the Tjip.Drawing.MultiIconEntry class.</summary>
		public MultiIconEntry() { }

		public byte Width { get; set; }
		public byte Height { get; set; }
		public byte ColorCount { get; set; }
		public byte Reserved { get; set; }
		public short Planes { get; set; }
		public short BitCount { get; set; }
		public int BytesInRes { get; set; }
		public int ImageOffset { get; set; }
	}

	/// <summary>Extension methods for MultiIconEntry.</summary>
	internal static class MultiIconEntryrExtensions
	{
		/// <summary>Reads a Windows (multi) icon entry from the current stream
		/// and advances the current position of the stream by sixteen bytes.
		/// </summary>
		/// <param name="reader">The reader.</param>
		public static MultiIconEntry ReadMultiIconEntry(this BinaryReader reader)
		{
			var entry = new MultiIconEntry()
			{
				Width = reader.ReadByte(),
				Height = reader.ReadByte(),
				ColorCount = reader.ReadByte(),
				Reserved = reader.ReadByte(),
				Planes = reader.ReadInt16(),
				BitCount = reader.ReadInt16(),
				BytesInRes = reader.ReadInt32(),
				ImageOffset = reader.ReadInt32(),
			};
			return entry;
		}

		/// <summary>Reads a Windows icon from the current stream
		/// and advances the current position of the stream to the end of the
		/// Windows icon in the stream.
		/// </summary>
		/// <param name="reader">The reader.</param>
		public static Icon ReadIcon(this BinaryReader reader, MultiIconHeader header, MultiIconEntry entry)
		{
			const short ICON_STREAM_START = 1;
			const int ICON_STREAM_OFFSET = 22;

			using (var newIcon = new MemoryStream())
			{
				using (var writer = new BinaryWriter(newIcon))
				{
					// Write it
					writer.Write(header.Reserved);
					writer.Write(header.Type);
					writer.Write(ICON_STREAM_START);
					writer.Write(entry.Width);
					writer.Write(entry.Height);
					writer.Write(entry.ColorCount);
					writer.Write(entry.Reserved);
					writer.Write(entry.Planes);
					writer.Write(entry.BitCount);
					writer.Write(entry.BytesInRes);
					writer.Write(ICON_STREAM_OFFSET);

					// Grab the icon
					byte[] tmpBuffer = new byte[entry.BytesInRes];
					reader.BaseStream.Position = entry.ImageOffset;
					reader.Read(tmpBuffer, 0, entry.BytesInRes);
					writer.Write(tmpBuffer);

					// Finish up
					writer.Flush();
					newIcon.Position = 0;
					return new Icon(newIcon);
				}
			}
		}

		/// <summary>Writes a Windows (multi) icon entry to the current stream
		/// and advances the current position of the stream by sixteen bytes.
		/// </summary>
		/// <param name="writer">The writer.</param>
		/// <param name="entry">The Windows multi icon entry to write.</param>
		public static void Write(this BinaryWriter writer, MultiIconEntry entry)
		{
			writer.Write(entry.Width);
			writer.Write(entry.Height);
			writer.Write(entry.ColorCount);
			writer.Write(entry.Reserved);
			writer.Write(entry.Planes);
			writer.Write(entry.BitCount);
			writer.Write(entry.BytesInRes);
			writer.Write(entry.ImageOffset);
		}
	}
}

It works perfectly. The only thing I still need to solve is the conversion of PNG24 to ICO:

var icon = Icon.FromHandle(new Bitmap(&quot;some_pgn24.png&quot;).GetHicon());

This results in an icon that does not have an alpha-channel. When I solved this, I will inform you.

Zeeman

Monday, July 19th, 2010

Nadat ik dinsdag nogal hard was afgestapt en een milde (nu ja mild) vorm van asfalteczeem had opgelopen was het een typisch geval van de wonden likken wassen met een washandje, en herstellen. Ook de kleding moest wat ruimer. Dus geen strakke jeans* spijkerbroek, maar ruimzittende trainings- annex joggingbroeken. In mijn gevalletje dus een een speciaal daarvoor aangeschaft exemplaar van de locale textielboer-schipper voor vijf euro.

Een echte beproeving was echter een weekendje zeilen met liefje en ex-huisgenoot en goede vriend E. Houd de wonden maar droog op een zeilboot, beweeg je met je verstijfde lijf maar eens op een schip, en ontzie je gekwetste zijde. Het is gelukt. Aan de andere kant: echt veel bewegingsruimte was er niet in het vooronder, dus het op een zijde liggen bleek geen kunst…

Afgestapt

Tuesday, July 13th, 2010

Wielrenners stappen niet graag af. Afstappen is einde koers. Afstappen is Did Not Finish: DNF. Afstappen doet een beetje zeer. En soms een beetje meer…

Het was een mooie dag op de Bult vandaag. De eerste ronde reed ik de bult op weg. Vier ronde lang bleef ik dat. Daarna handhaafde ik mij soepel in het peloton. Na een tweede uitval was ik minder gelukkig: Bij het bijhalen tikte de eerste renner van het peloton m’n stuur aan. Voor ik er erg in had was ik afgestapt. Iets te hard helaas.

Gelukkig hebben we de foto’s nog:

Tijdritspecialist?!

Monday, July 12th, 2010

Ik heb enige tijd geleden geblogd over mijn avonturen als testpiloot. In het altijd pittoreske Goirle namen wij vier tijdritfietsen (instapmodellen) de maat. Typeerde ik mijzelf in dit blogsel nog als tijdritjunk, Fiets magazine schat mijn mening kennlijk hoger in: “Tijdritspecialist te Leiden (..)” Je zou er van naast je schoenen gaan lopen. (Als je ze niet zou zijn vergeten)

In deze editie van Fiets magazine stond het tijdrijden dus centraal. Ook de Barry en Bep:

Op het forum zag danny1407 analogieën. Ik niet: ik reed toch echt 1:05:32 tijdens de TijdstrijdersCup

Enfin, positieve aandacht voor deze mooie discipline binnen het wielrennen. En ik heb daar een steentje aan bij mogen dragen. Nu hopen dat de KNWU het licht ook nog eens gaat zien.

Aap

Saturday, July 10th, 2010

Als de berg Timo niet naar Mohammed Aap komt, zal Mohammed Aap naar de berg Timo moeten gaan. En aangezien Aap zelf niet al te mobiel is, was het aan oom Corniel en tante L. om een en ander te bewerkstelligen.

De oto van oom en tante was echter ook bij Timo, dus er zat niets anders op dan zon, hitte, en windstilte (nu zowaar een nadeel) te trotseren. De route was 86 kilometer lang en leidde ons langs een bekende route: Leiden, Leidschendam, Nootdorp, Pijnacker, Delft, Schipluiden, Maasland, Maassluis, Rozenburg, Vierpolders, Voorne-Putten, Nieuwenhoorn, Stellendam, Melissant en eindbestemming Herkingen casa Timo.

Het was warm, dus tante en oom deden het op het gemakkie. Er werd zelfs een heuze stop ingelast om wat te eten en te drinken.

Uiteindelijk werken Timo en Aap weer verenigd (en hadden wij onze oto terug). En dat was het belangrijkste.

Donner

Thursday, July 8th, 2010

Jan Hein Donner spraak ooit de woorden: “Ik heb nog nooit van een gezonde schaker gewonnen (..)”

Vandaag hoefde ik niet te schaken, en ziek was ik ook al niet. Excuses had ik echter te over:

  1. Het was extreem warm (en benauwd).
  2. Ik deed (gedwongen, de oto was stuk) een Van-der-Poeltje die 52 kilometer was (15 kilometer langer dan gepland).
  3. Ik had te weinig tijd om te rusten tot ik van start moest.
  4. Ik had te weinig gedronken.
  5. De dag ervoor had ik een hele zware inspanningstest ondergaan.

Kortom, het was een wonder dat ik ondanks dit alles, met 21:09 zo dicht bij m’n pr zat…