<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Galfar's Lair &#187; Programming</title>
	<atom:link href="http://galfar.vevb.net/wp/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://galfar.vevb.net/wp</link>
	<description>Oh hai!</description>
	<lastBuildDate>Thu, 08 Dec 2011 14:06:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Photo Sorting Tool</title>
		<link>http://galfar.vevb.net/wp/2011/photo-sorting-tool/</link>
		<comments>http://galfar.vevb.net/wp/2011/photo-sorting-tool/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 23:15:56 +0000</pubDate>
		<dc:creator>Marek Mauder</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Pascal & Delphi]]></category>
		<category><![CDATA[PhotoMixer]]></category>

		<guid isPermaLink="false">http://galfar.vevb.net/wp/?p=825</guid>
		<description><![CDATA[Let&#8217;s say you have just spent few weeks in some exotic country with a bunch of friends. Everyone had a digital camera and made thousands of photos. Now you have several directories with hordes of oddly named photos and you &#8230; <a href="http://galfar.vevb.net/wp/2011/photo-sorting-tool/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say you have just spent few weeks in some exotic country with a bunch of friends. Everyone had a digital camera and made thousands of photos. Now you have several directories with hordes of oddly named photos and you just want see all of them in the order they were taken. Throwing them all in one folder and setting file ordering by date might help but everyone&#8217;s camera can have a different internal time. File system dates can also be lost on their way to you (FTP upload etc.).</p>
<p>Being a programmer, rather that searching for some program on the Internet, I wrote my own quick and dirty command line tool for this task (mostly hard-coded paths etc.) in mid 2010. This year, I added GUI (where all the settings can be adjusted), some more date &amp; time functions, and basically made the whole thing usable. And finally, beta release of PhotoMixer is available.<br />
<span id="more-825"></span></p>
<h2>Download</h2>
Note: There is a file embedded within this post, please visit this post to download the file.
<p>Please report any bugs and problems you encounter. Ideas for new features as well!</p>
<h2>Overview</h2>
<p>PhotoMixer takes <em>photo sources</em> as input and mixes/sorts them. Photo source is a folder with photos that have different properties than some other source. Most often, it&#8217;s from a different person and/or taken with different camera. PhotoMixer takes all the photos from all sources and puts them all in one output folder with file names that contain timestamps (so that the files appear in the same order regardless if you sort them by name, type, or date).</p>
<p>The most important this is: <em>it can adjust date &amp; time of photos from each source automatically</em>. As the result, you now have a folder with all the photos from your trip in the right order even though they originally came from ten people with all of them having wrong date &amp; time setting in their cameras. Where&#8217;s the catch? Well, there should be one photo that each of these people took at nearly the same time. These reference photos are then used by PhotoMixer to synchronize the sources.</p>
<p>Each source can be synchronized using reference photo or just by explicit time shift. Photo date and time is taken from embedded EXIF metadata that&#8217;s generated by digital camera and inserted in JPEG file. Only when, for some reason, EXIF is not present, file system date is used instead. When using reference photo synchronization one of the sources must be designated as <em>main reference source</em>. That is the source whose dates will not be modified and all other sources will be shifted in regard to date differences between their reference photo and that of the main source.</p>
<p>PhotoMixer also offers some useful tools for related tasks.</p>
<h2>Usage Guide</h2>
<p>PhotoMixer employs tabbed user interface where the first tab contains output settings and log. Additional tabs define photo sources. When you start the tool for the first time new source is created, and you can start setting it up and adding more sources. When you are done with sources, go to <em>Settings</em> tab, adjust output options, and finally click <em>Run</em> button.</p>
<div id="attachment_901" class="wp-caption aligncenter" style="width: 410px"><a href="http://galfar.vevb.net/wp/wp-content/uploads/2011/12/Capture2.png"><img class="size-medium wp-image-901" title="Photo source options" src="http://galfar.vevb.net/wp/wp-content/uploads/2011/12/Capture2-400x347.png" alt="" width="400" height="347" /></a><p class="wp-caption-text">Photo source options</p></div>
<p>For each source you can select folder with photos and type of synchronization. For sync by reference photo you must select this photo and for explicit shift you provide positive or negative time in seconds.</p>
<div id="attachment_900" class="wp-caption aligncenter" style="width: 410px"><a href="http://galfar.vevb.net/wp/wp-content/uploads/2011/12/Capture1.png"><img class="size-medium wp-image-900" title="Settings and output tab" src="http://galfar.vevb.net/wp/wp-content/uploads/2011/12/Capture1-400x347.png" alt="" width="400" height="347" /></a><p class="wp-caption-text">Settings and output tab</p></div>
<p>On <em>Settings</em> tab select the output folder, base name of the generated files (will be named &#8220;BaseName TimeStamp.jpg&#8221;), and main reference source used for synchronization.</p>
<p>All the options and source definitions can be saved for later usage and restored using the <em>Save</em> and <em>Load</em> actions in the <em>Tools</em> menu. There is also tool for clearing the output folder and two little more complex tools: <em>Set Photo Date &amp; Time</em> and <em>Set File Time from Photo Metadata</em>.</p>
<div id="attachment_902" class="wp-caption aligncenter" style="width: 410px"><a href="http://galfar.vevb.net/wp/wp-content/uploads/2011/12/Capture3.png"><img class="size-medium wp-image-902" title="&quot;Set Photo Date &amp; Time&quot; tool" src="http://galfar.vevb.net/wp/wp-content/uploads/2011/12/Capture3-400x200.png" alt="" width="400" height="200" /></a><p class="wp-caption-text">&quot;Set Photo Date &amp; Time&quot; tool</p></div>
<p>If you totally lost all date &amp; time info about some photos and you want at least something (e.g. you use some photo organizer and want some filtering based on year &amp; month to work) you can generate it using Set Photo Date &amp; Time tool. Some base date &amp; time is selected and each photo can have optional time increment (e.g. first photo has &#8220;base time&#8221;, second has &#8220;base time + 5 minutes&#8221;, another one has &#8220;base time + 10 minutes&#8221;, etc.).</p>
<p>Set File Time from Photo Metadata tool can be used to restore file system date &amp; time according to metadata inside the photo.</p>
<h2>Nice to have features for future version</h2>
<p>Some are definitely going to be included, some are more like pipe dreams.</p>
<ul>
<li>Detect blurred photos that you just want to delete.</li>
<li>Detect similar images &#8211; often more people take a photo of the same thing but you want to keep just one (the best looking one).</li>
<li>Resampling of output photos to different resolution. Although this is a lossy operation, it has its uses.</li>
<li>Create embedded JPEG thumbnails where missing (they&#8217;re embedded by cameras but some photo editing program could remove it).</li>
<li>Lossless rotation of MJPEG videos from cameras (90/180/270 rotations).</li>
<li>Strip junk data streams (e.g. after lossless rotation in Irfan the old data stream is kept in the file resulting in 2x bigger file).</li>
<li>Linux and Mac OS X version (at least with CLI).</li>
<li>Something to deal with camera orientation (when taking the photo). Some cameras have positioning sensor and store this information in metadata so the program could rotate them accordingly. For others, some GUI that allows simple and fast manual rotations would be nice. Probably redundant: probably just do it in Live Gallery/Picassa/whatever.</li>
</ul>
<h2>The End</h2>
<p>Sorting of about 3000 photos too about 2 minutes on my desktop (nearly all of that time is spent reading EXIF metadata from the files). Here are some photos from the &#8220;last batch&#8221; (panoramas made in Microsoft ICE):</p>
<p><a href="http://galfar.vevb.net/wp/wp-content/uploads/2011/12/Island2.jpg"><img class="aligncenter size-large wp-image-908" title="Iceland" src="http://galfar.vevb.net/wp/wp-content/uploads/2011/12/Island2-800x299.jpg" alt="" width="584" height="218" /></a><br />
<a href="http://galfar.vevb.net/wp/wp-content/uploads/2011/12/Island1.jpg"><img class="aligncenter size-large wp-image-907" title="Iceland" src="http://galfar.vevb.net/wp/wp-content/uploads/2011/12/Island1-800x330.jpg" alt="" width="584" height="240" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://galfar.vevb.net/wp/2011/photo-sorting-tool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>16bit half float in Pascal/Delphi</title>
		<link>http://galfar.vevb.net/wp/2011/16bit-half-float-in-pascaldelphi/</link>
		<comments>http://galfar.vevb.net/wp/2011/16bit-half-float-in-pascaldelphi/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 14:10:41 +0000</pubDate>
		<dc:creator>Marek Mauder</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Pascal & Delphi]]></category>

		<guid isPermaLink="false">http://galfar.vevb.net/wp/?p=801</guid>
		<description><![CDATA[Floating point numbers with 16 bits of precision are used mostly in computer graphics. They are also called half precision floating point numbers (as having half the bits of single precision 32bit floats). There&#8217;s one sign bit, five bit exponent, &#8230; <a href="http://galfar.vevb.net/wp/2011/16bit-half-float-in-pascaldelphi/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Floating point numbers with 16 bits of precision are used mostly in computer graphics. They are also called half precision floating point numbers (as having half the bits of single precision 32bit floats). There&#8217;s one sign bit, five bit exponent, and ten bits for mantissa. Half floats are not really meant to be used for arithmetic computations due to the limited precision (and no support in common CPUs/FPUs).</p>
<p>Half floats first appeared in early 2000s as samples in images and textures. Floats provide higher dynamic range than what is available with regular 8bit or 16bit integer samples. On the other hand, commonly used single and double precision floats have much higher memory cost per pixel. Half floats have more reasonable memory requirements and their precision is adequate for many usages in imaging.</p>
<p>16bit float formats have been supported by ATI and NVidia GPUs for many years. I&#8217;m not sure about other IHVs but at least Direct3D 10 capable GPUs should all support it.</p>
<p>Read on if your interested how to convert between half and single precision floats (Object Pascal code).</p>
<p><span id="more-801"></span></p>
<h3>Half/Single Conversion code</h3>
<p>Finally, here&#8217;s the code for converting to half floats and back to single precision float. It&#8217;s based on C++ code from OpenEXR library (half class).</p>
<h4>First some types and constants</h4>
<p>Note that THalfFloat type is just an alias for Word.</p>
<pre class="brush: delphi; title: ; notranslate">
type
  THalfFloat = type Word;

const
  HalfMin:     Single = 5.96046448e-08; // Smallest positive half
  HalfMinNorm: Single = 6.10351562e-05; // Smallest positive normalized half
  HalfMax:     Single = 65504.0;        // Largest positive half
  // Smallest positive e for which half (1.0 + e) != half (1.0)
  HalfEpsilon: Single = 0.00097656;
  HalfNaN:     THalfFloat = 65535;
  HalfPosInf:  THalfFloat = 31744;
  HalfNegInf:  THalfFloat = 64512;
</pre>
<h4>Single precision float to half</h4>
<pre class="brush: delphi; title: ; notranslate">
function FloatToHalf(Float: Single): THalfFloat;
var
  Src: LongWord;
  Sign, Exp, Mantissa: LongInt;
begin
  Src := PLongWord(@Float)^;
  // Extract sign, exponent, and mantissa from Single number
  Sign := Src shr 31;
  Exp := LongInt((Src and $7F800000) shr 23) - 127 + 15;
  Mantissa := Src and $007FFFFF;

  if (Exp &gt; 0) and (Exp &lt; 30) then
  begin
    // Simple case - round the significand and combine it with the sign and exponent
    Result := (Sign shl 15) or (Exp shl 10) or ((Mantissa + $00001000) shr 13);
  end
  else if Src = 0 then
  begin
    // Input float is zero - return zero
    Result := 0;
  end
  else
  begin
    // Difficult case - lengthy conversion
    if Exp &lt;= 0 then
    begin
      if Exp &lt; -10 then
      begin
        // Input float's value is less than HalfMin, return zero
         Result := 0;
      end
      else
      begin
        // Float is a normalized Single whose magnitude is less than HalfNormMin.
        // We convert it to denormalized half.
        Mantissa := (Mantissa or $00800000) shr (1 - Exp);
        // Round to nearest
        if (Mantissa and $00001000) &gt; 0 then
          Mantissa := Mantissa + $00002000;
        // Assemble Sign and Mantissa (Exp is zero to get denormalized number)
        Result := (Sign shl 15) or (Mantissa shr 13);
      end;
    end
    else if Exp = 255 - 127 + 15 then
    begin
      if Mantissa = 0 then
      begin
        // Input float is infinity, create infinity half with original sign
        Result := (Sign shl 15) or $7C00;
      end
      else
      begin
        // Input float is NaN, create half NaN with original sign and mantissa
        Result := (Sign shl 15) or $7C00 or (Mantissa shr 13);
      end;
    end
    else
    begin
      // Exp is &gt; 0 so input float is normalized Single

      // Round to nearest
      if (Mantissa and $00001000) &gt; 0 then
      begin
        Mantissa := Mantissa + $00002000;
        if (Mantissa and $00800000) &gt; 0 then
        begin
          Mantissa := 0;
          Exp := Exp + 1;
        end;
      end;

      if Exp &gt; 30 then
      begin
        // Exponent overflow - return infinity half
        Result := (Sign shl 15) or $7C00;
      end
      else
        // Assemble normalized half
        Result := (Sign shl 15) or (Exp shl 10) or (Mantissa shr 13);
    end;
  end;
end;
</pre>
<h4>Half to single precision float</h4>
<pre class="brush: delphi; title: ; notranslate">
function HalfToFloat(Half: THalfFloat): Single;
var
  Dst, Sign, Mantissa: LongWord;
  Exp: LongInt;
begin
  // Extract sign, exponent, and mantissa from half number
  Sign := Half shr 15;
  Exp := (Half and $7C00) shr 10;
  Mantissa := Half and 1023;

  if (Exp &gt; 0) and (Exp &lt; 31) then
  begin
    // Common normalized number
    Exp := Exp + (127 - 15);
    Mantissa := Mantissa shl 13;
    Dst := (Sign shl 31) or (LongWord(Exp) shl 23) or Mantissa;
    // Result := Power(-1, Sign) * Power(2, Exp - 15) * (1 + Mantissa / 1024);
  end
  else if (Exp = 0) and (Mantissa = 0) then
  begin
    // Zero - preserve sign
    Dst := Sign shl 31;
  end
  else if (Exp = 0) and (Mantissa &lt;&gt; 0) then
  begin
    // Denormalized number - renormalize it
    while (Mantissa and $00000400) = 0 do
    begin
      Mantissa := Mantissa shl 1;
      Dec(Exp);
    end;
    Inc(Exp);
    Mantissa := Mantissa and not $00000400;
    // Now assemble normalized number
    Exp := Exp + (127 - 15);
    Mantissa := Mantissa shl 13;
    Dst := (Sign shl 31) or (LongWord(Exp) shl 23) or Mantissa;
    // Result := Power(-1, Sign) * Power(2, -14) * (Mantissa / 1024);
  end
  else if (Exp = 31) and (Mantissa = 0) then
  begin
    // +/- infinity
    Dst := (Sign shl 31) or $7F800000;
  end
  else //if (Exp = 31) and (Mantisa &lt;&gt; 0) then
  begin
    // Not a number - preserve sign and mantissa
    Dst := (Sign shl 31) or $7F800000 or (Mantissa shl 13);
  end;

  // Reinterpret LongWord as Single
  Result := PSingle(@Dst)^;
end;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://galfar.vevb.net/wp/2011/16bit-half-float-in-pascaldelphi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deskewing Scanned Documents</title>
		<link>http://galfar.vevb.net/wp/2011/deskewing-scanned-documents/</link>
		<comments>http://galfar.vevb.net/wp/2011/deskewing-scanned-documents/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 23:16:57 +0000</pubDate>
		<dc:creator>Marek Mauder</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Pascal & Delphi]]></category>
		<category><![CDATA[Vampyre Imaging Library]]></category>

		<guid isPermaLink="false">http://galfar.vevb.net/wp/?p=777</guid>
		<description><![CDATA[Some time ago I wrote a simple command line tool for deskewing scanned documents called Deskew. Technically, it&#8217;s a rotation since angles are preserved and skew transformation doesn&#8217;t do that. However, deskewing is commonly used term in this context. My &#8230; <a href="http://galfar.vevb.net/wp/2011/deskewing-scanned-documents/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Some time ago I wrote a simple command line tool for deskewing scanned documents called <em>Deskew</em>. Technically, it&#8217;s a rotation since angles are preserved and skew transformation doesn&#8217;t do that. However, deskewing is commonly used term in this context.</p>
<div id="attachment_782" class="wp-caption aligncenter" style="width: 410px"><a href="http://galfar.vevb.net/wp/wp-content/uploads/2010/12/deskew2.jpg"><img class="size-medium wp-image-782" title="Deskewing some smart paper" src="http://galfar.vevb.net/wp/wp-content/uploads/2010/12/deskew2-400x266.jpg" alt="" width="400" height="266" /></a><p class="wp-caption-text">Deskewing some smart paper</p></div>
<p>My approach is fairly common for this problem &#8211; rotation angle is first determined using <a href="http://en.wikipedia.org/wiki/Hough_transform" target="_blank">Hough transform</a> and then the image is rotated accordingly. Classical Hough transform is able identify lines in the image and it was later extended to allow detection of any arbitrary shapes.</p>
<p>Lines of text can be thought of as horizontal lines in the image. In a skewed scanned document all the lines will be rotated by some small angle. We can start with the equation of the line <em>y = k <em>·</em> x + q</em>. Since we&#8217;re interested in the angle, we can rewrite it as <em>y = (sin(α) / cos(α)) <em>·</em> x + q</em>. Finally, we can rearrange it as <em>y <em>·</em> cos(α) − x · sin(α) = d</em>. Now every point <em>[x, y]</em> in the image can have infinite number of lines going through it, where each is defined by two parameters: angle <em>α</em> and distance from the origin <em>d</em>.</p>
<p>We want to consider lines only for certain points of input image. Ideally, that would be the base lines on which the &#8220;text is sitting&#8221;. Simple way of determining these points is to check for black pixels which have white pixels just below them. Now for each of the classified points, we determine parameters <em>α</em> and <em>d</em> for all the lines that go through them. To get some finite number of lines, we calculate <em>d</em> for angles <em>α</em> from a certain range (I use angle step of 0.1 degrees). We want to find a line that intersects as many classified points as possible – an accumulator is used to store &#8220;votes&#8221; for each calculated line. For each point that is believed to be on the text base line, we add one vote for each line that intersects it. At the end, we find the top lines that have the most votes. Ideally, these are the base lines of all lines of text in the document. Finally, we get the rotation angle by averaging angle <em>α</em> of the top lines and rotate the whole image accordingly.</p>
<p>Important part is that one: <em>&#8220;check for black pixels which have white pixels just below&#8221;</em>. What&#8217;s black and white is determined by comparing value of the current pixel against some given threshold. For images where background is plain white and the text is black it&#8217;s easy just to use 0.5 as the threshold. But when the background/foreground distinction is not so sharp calculating the threshold adaptively based on the current image can be very useful. <em>Deskew</em> supports both adaptive threshold calculation as well as specifying constant threshold as command line parameter.</p>
<div id="attachment_781" class="wp-caption aligncenter" style="width: 410px"><a href="http://galfar.vevb.net/wp/wp-content/uploads/2010/12/deskew1.jpg"><img class="size-medium wp-image-781" title="Deskewing some math exercise" src="http://galfar.vevb.net/wp/wp-content/uploads/2010/12/deskew1-400x261.jpg" alt="" width="400" height="261" /></a><p class="wp-caption-text">Deskewing some math exercise</p></div>
<p>Implementation is written in Object Pascal and uses Imaging library for reading and writing various image file formats. There are precompiled binaries for 32bit Windows and Linux, other platforms can be built from sources using Free Pascal compiler (you need Imaging library for compilation). Archive also contains few test images.</p>
Note: There is a file embedded within this post, please visit this post to download the file.
]]></content:encoded>
			<wfw:commentRss>http://galfar.vevb.net/wp/2011/deskewing-scanned-documents/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Ugly Images of Disabled Menu Items in Delphi</title>
		<link>http://galfar.vevb.net/wp/2010/ugly-images-of-disabled-items-in-delphi/</link>
		<comments>http://galfar.vevb.net/wp/2010/ugly-images-of-disabled-items-in-delphi/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 15:44:14 +0000</pubDate>
		<dc:creator>Marek Mauder</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Pascal & Delphi]]></category>

		<guid isPermaLink="false">http://galfar.vevb.net/wp/?p=726</guid>
		<description><![CDATA[Ever used 32bit images stored in TImageList in your Delphi application? Toolbars and some other VCL controls have DisabledImages property which is automatically used to get images for disabled toolbar buttons. But what about menu components? They don&#8217;t have this &#8230; <a href="http://galfar.vevb.net/wp/2010/ugly-images-of-disabled-items-in-delphi/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Ever used 32bit images stored in TImageList in your Delphi application? Toolbars and some other VCL controls have DisabledImages property which is automatically used to get images for disabled toolbar buttons. But what about menu components? They don&#8217;t have this property and drawing of disabled images is handled by TImageList with original enabled images (TMainMenu.Images property).  And the results are really abysmal. How can this be fixed?</p>
<p><a href="http://galfar.vevb.net/wp/wp-content/uploads/2010/04/disabled-items-delphi.png"><img class="aligncenter size-full wp-image-731" title="Disabled menu items" src="http://galfar.vevb.net/wp/wp-content/uploads/2010/04/disabled-items-delphi.png" alt="" width="153" height="190" /></a>One way is to override DoDraw method of TImageList and change the code that draws disabled images. You can do regular RGB to grayscale conversion here or let  Windows draw it for you in grayscale with nearly no work on your part. You can do this by using <a href="http://msdn.microsoft.com/en-us/library/bb761537(VS.85).aspx" target="_blank">ImageList_DrawIndirect</a> with ILS_SATURATE parameter. Note that this works only on Windows XP and newer and for 32bit images only. For older targets or color depths doing your own RGB-&gt;grayscale conversion is an option (good idea would probably be to cache converted grayscale images somewhere so they won&#8217;t need to be converted on every draw call).</p>
<p>Here&#8217;s the code of DoDraw method using  ILS_SATURATE:</p>
<pre class="brush: delphi; title: ; notranslate">
type
// Descendant of regular TImageList
TSIImageList = class(TImageList)
protected
  procedure DoDraw(Index: Integer; Canvas: TCanvas; X, Y: Integer;
    Style: Cardinal; Enabled: Boolean = True); override;
end;

procedure TSIImageList.DoDraw(Index: Integer; Canvas: TCanvas; X, Y: Integer;
  Style: Cardinal; Enabled: Boolean);
var
  Options: TImageListDrawParams;

  function GetRGBColor(Value: TColor): Cardinal;
  begin
    Result := ColorToRGB(Value);
    case Result of
      clNone: Result := CLR_NONE;
      clDefault: Result := CLR_DEFAULT;
    end;
  end;

begin
  if Enabled or (ColorDepth &lt;&gt; cd32Bit) then
    inherited
  else if HandleAllocated then
  begin
    FillChar(Options, SizeOf(Options), 0);
    Options.cbSize := SizeOf(Options);
    Options.himl := Self.Handle;
    Options.i := Index;
    Options.hdcDst := Canvas.Handle;
    Options.x := X;
    Options.y := Y;
    Options.cx := 0;
    Options.cy := 0;
    Options.xBitmap := 0;
    Options.yBitmap := 0;
    Options.rgbBk := GetRGBColor(BkColor);
    Options.rgbFg := GetRGBColor(BlendColor);
    Options.fStyle := Style;
    Options.fState := ILS_SATURATE; // Grayscale for 32bit images

    ImageList_DrawIndirect(@Options);
  end;
end;
</pre>
<p><strong>Important note: </strong>For ILS_SATURATE to work correctly source image files must be 32bit with proper alpha channel data, setting color depth of TImageList to 32bit is not enough! If you don&#8217;t see any images drawn this is probably the cause: 8/24bit image is loaded from file and then inserted into 32bit TImageList. As there is no alpha channel data in source image it is drawn as fully transparent so you don&#8217;t see anything.</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">http://msdn.microsoft.com/en-us/library/bb761537(VS.85).aspx</div>
]]></content:encoded>
			<wfw:commentRss>http://galfar.vevb.net/wp/2010/ugly-images-of-disabled-items-in-delphi/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Shift Right: Delphi vs C</title>
		<link>http://galfar.vevb.net/wp/2009/shift-right-delphi-vs-c/</link>
		<comments>http://galfar.vevb.net/wp/2009/shift-right-delphi-vs-c/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 14:33:59 +0000</pubDate>
		<dc:creator>Marek Mauder</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Pascal & Delphi]]></category>

		<guid isPermaLink="false">http://galfar.vevb.net/wp/?p=605</guid>
		<description><![CDATA[Few weeks ago I converted a little function from C language to Delphi. I kept getting completely wrong results all the time even though I was sure the C to Pascal conversion was right (it was really just few lines). &#8230; <a href="http://galfar.vevb.net/wp/2009/shift-right-delphi-vs-c/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Few weeks ago I converted a little function from C language to Delphi. I kept getting completely wrong results all the time even though I was sure the C to Pascal conversion was right (it was really just few lines). After some desperate time, I just tried replacing <strong>SHR</strong> operator by normal <strong>DIV</strong> (as A SHR 1 = A DIV 2 and so on). To my surprise, I immediately got the right results. Can Delphi&#8217;s (I didn&#8217;t test it in Free Pascal) <strong>SHR</strong> operator behave differently than C&#8217;s <strong>&gt;&gt;</strong> operator?</p>
<p>It does in fact. SHR treats its first operand as unsigned value even though it is a variable of signed type whereas &gt;&gt; takes the sign bit into account. In the function I converted the operand for right shift was often negative and Delphi&#8217;s SHR just ignored the value of the sign bit.</p>
<h3>A Bit of Code</h3>
<pre class="brush: cpp; title: ; notranslate">
int a, b1, b2;
a = -512;
b1 = a &gt;&gt; 1;
b2 = a / 2;
</pre>
<p>After running this C code both <strong>b1</strong> and <strong>b2</strong> have a value of -256.</p>
<pre class="brush: delphi; title: ; notranslate">
var A, B1, B2: Integer;
A := -512;
B1 := A shr 1;
B2 := A div 2;
</pre>
<p>This Delphi code however yields different result: <strong>B2</strong> is -256 as expected but <strong>B1</strong> has a value of 2147483392.</p>
<h3>A Bit of Assembler</h3>
<p>Assembler output of C code:</p>
<pre class="brush: plain; title: ; notranslate">
Unit1.cpp.22: b1 = a &gt;&gt; 1;
mov eax,[ebp-$0c]
sar eax,1
mov [ebp-$10],eax
Unit1.cpp.23: b2 = a / 2;
mov edx,[ebp-$0c]
sar edx,1
jns $00401bb9
adc edx,$00
mov [ebp-$14],edx
</pre>
<p>Assembler output of Delphi code:</p>
<pre class="brush: plain; title: ; notranslate">
Unit1.pas.371: B1 := A shr 1;
mov eax,[ebp-$0c]
shr eax,1
mov [ebp-$1c],eax
Unit1.pas.373: B2 := A div 2;
mov eax,[ebp-$0c]
sar eax,1
jns $00565315
adc eax,$00
mov [ebp-$20],eax
</pre>
<p>As you can see, asm output of C and Delphi divisions is identical. What differs is asm for shift right operator. Delphi uses <strong>shr</strong> instruction whereas C uses <strong>sar</strong> instruction. The difference: shr does logical shift and sar does arithmetic one.</p>
<blockquote><p>The SHR instruction clears the most significant bit (see Figure 6-7 in the Intel Architecture Software Developer&#8217;s Manual, Volume 1); the SAR instruction sets or clears the most significant bit to correspond to the sign (most significant bit) of the original value in the destination operand.</p></blockquote>
<p>Quoted from: <a href="http://faydoc.tripod.com/cpu/shr.htm">http://faydoc.tripod.com/cpu/shr.htm</a></p>
]]></content:encoded>
			<wfw:commentRss>http://galfar.vevb.net/wp/2009/shift-right-delphi-vs-c/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Working in MODULA-2</title>
		<link>http://galfar.vevb.net/wp/2009/working-in-modula-2/</link>
		<comments>http://galfar.vevb.net/wp/2009/working-in-modula-2/#comments</comments>
		<pubDate>Fri, 10 Apr 2009 10:36:37 +0000</pubDate>
		<dc:creator>Marek Mauder</dc:creator>
				<category><![CDATA[General News]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://galfar.vevb.net/wp/2009/04/working-in-modula-2/</guid>
		<description><![CDATA[I’ve been working in Modula-2 for last few weeks. It’s a considered a dead language now, one of Pascal’s descendants designed by Niclaus Wirth. I’ve been doing some updates to quite an old project, embedded system for military usage.&#160; I &#8230; <a href="http://galfar.vevb.net/wp/2009/working-in-modula-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I’ve been working in Modula-2 for last few weeks. It’s a considered a dead language now, one of Pascal’s descendants designed by Niclaus Wirth. I’ve been doing some updates to quite an old project, embedded system for military usage.&#160; I had to run Mac OS 7.5 emulator to get original 1989 compiler running. Modula-2 dialect understood by this compiler is quite strict – you cannot even mix cardinal and integer numbers without explicitly converting one of them. </p>
<p>First difference you may notice (compared to Pascal) is case sensitiveness of Modula-2, for instance all reserved words are upper cased. You don’t have to write so many begin-end statements though. Another C-like trait is importance of header files (definition modules) order during compiling – just change it a little bit in a large project and whole thing breaks down. </p>
<p align="left">More info about Modula-2 if you’re interested: <a href="http://www.modula2.org/">http://www.modula2.org/</a>.</p>
<p align="left"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="Modula-2" border="0" alt="Modula-2" src="http://galfar.vevb.net/wp/wp-content/uploads/2009/04/modula2.png" width="448" height="480" /></p>
]]></content:encoded>
			<wfw:commentRss>http://galfar.vevb.net/wp/2009/working-in-modula-2/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
