<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>[C]how to zoom an image with bilinear-interpolation</title>
		<link>http://www.allegro.cc/forums/view/600753</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Wed, 01 Jul 2009 18:03:52 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>hi,<br />I&#39;m writing to know if exist some function in allegro library for 	<br />enlarging an image (BW) with bilinear-intepolation<br />THANKS???
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (jack_folla)</author>
		<pubDate>Tue, 30 Jun 2009 19:53:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Not in the 4.2 branch, no.<br />You have several options:<br />a) use the 4.9 allegro branch instead<br />b) use allegrogl and ideally some opengl calls to render your graphics (opengl gives you a lot of control over resizing algorithms and such)<br />c) see if you can find an add-on for allegro that does this in software (but be prepared that software resizing is a lot slower)<br />d) code your own routine that does this; this is probably the worst solution, unless you are a graphics programming wizard of some sort
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Tue, 30 Jun 2009 21:01:21 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>i add some useful information:<br />-i need to scale up an image (black&amp;white) into anotherone with no pre-defined scale-up ratio <br />(the dimension of the output image is known)<br />-i need to do this using c language <br />(i need to use this code into matlab throw mex-file)<br />-what do you mean for 4.9 allegro branch?<br />thanks
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (jack_folla)</author>
		<pubDate>Tue, 30 Jun 2009 22:05:07 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/600753/819052#target">jack_folla</a> said:</div><div class="quote"><p>
-i need to scale up an image (black&amp;white) into anotherone with no pre-defined scale-up ratio<br />(the dimension of the output image is known)
</p></div></div><p>
The ratio can be calculated from the source and destination image sizes, so this is pretty irrelevant.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
-i need to do this using c language 
</p></div></div><p>
All the solutions I mentioned are possible using C. Allegro, AllegroGL, and OpenGL are all C libraries.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
-what do you mean for 4.9 allegro branch?
</p></div></div><p>
What I said. The 4.9 branch, that is, versions starting with 4.9. <br />Some background on this: The current stable version of allegro is 4.2.something, and development on that has pretty much come to a halt. Some bugfix releases may be made, but I doubt even that is going to happen.<br />The next stable release will be a major rewrite with a new API, which will be incompatible with previous versions; the version number is probably going to be 5.0. The &#39;unstable&#39; versions preceding it carry numbers starting with 4.9, just like the unstable versions leading to 4.2.x are 4.1.x.<br />The allegro rewrite includes hardware acceleration (through OpenGL and, if you&#39;re on windows, DirectX), and will take advantage of it wherever this makes sense.</p><p>The 4.2 versions don&#39;t have hardware acceleration (at least not beyond some fairly limited video-video blitting and special CPU operations), but you can use the alleggl add-on to enable the GFX_OPENGL driver, and use OpenGL commands to draw things (including textured quads, which is exactly what you need to scale an image).</p><p>If real-time performance is not required, I recommend you write the conversion routine yourself. It&#39;s not THAT hard, really, especially when it&#39;s just black &amp; white.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Wed, 01 Jul 2009 02:02:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If it doesn&#39;t need to be realtime, you can check my implementation of a software bilinear re-size, which can be found in the <a href="http://wiki.allegro.cc/index.php?title=Bilinear_resize">allegro wiki</a>. If you only want magnifying then forget about the reduce_mipmap function, that&#39;s only useful (for better quality) for scaling down. It&#39;s pretty optimized, but probably it still cannot be used for realtime resizing (though I haven&#39;t tested with a modern computer, when I wrote this I was using a Pentium 166 <img src="http://www.allegro.cc/forums/smileys/cheesy.gif" alt=":D" />). If you need any help using it just ask.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Oscar Giner)</author>
		<pubDate>Wed, 01 Jul 2009 09:18:13 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>i&#39;ve just seen your implementation of the software bilinear re-size,but  there were some problem:<br />-my image is no a bitmap file but a matrix of double<br />- i dont need to scale up an RGB image,my object as i&#39;ve just said is a matrix of double and it represents a B&amp;W image<br />is it possible to easily adapt your code?in wich way?<br />thanks
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (jack_folla)</author>
		<pubDate>Wed, 01 Jul 2009 11:04:13 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>In bilinear upscaling, the pixel drawn from (x, y) of the original image can be found by (in pseudocode):
</p><div class="source-code snippet"><div class="inner"><pre>colourTopLeft <span class="k3">=</span> pixel at <a href="http://www.delorie.com/djgpp/doc/libc/libc_330.html" target="_blank">floor</a><span class="k2">(</span>x<span class="k2">)</span>, <a href="http://www.delorie.com/djgpp/doc/libc/libc_330.html" target="_blank">floor</a><span class="k2">(</span>y<span class="k2">)</span>
colourTopRight <span class="k3">=</span> pixel at <a href="http://www.delorie.com/djgpp/doc/libc/libc_83.html" target="_blank">ceil</a><span class="k2">(</span>x<span class="k2">)</span>, <a href="http://www.delorie.com/djgpp/doc/libc/libc_330.html" target="_blank">floor</a><span class="k2">(</span>y<span class="k2">)</span>
colourBottomLeft <span class="k3">=</span> pixel at <a href="http://www.delorie.com/djgpp/doc/libc/libc_330.html" target="_blank">floor</a><span class="k2">(</span>x<span class="k2">)</span>, <a href="http://www.delorie.com/djgpp/doc/libc/libc_83.html" target="_blank">ceil</a><span class="k2">(</span>y<span class="k2">)</span>
colourBottomRight <span class="k3">=</span> pixel at <a href="http://www.delorie.com/djgpp/doc/libc/libc_83.html" target="_blank">ceil</a><span class="k2">(</span>x<span class="k2">)</span>, <a href="http://www.delorie.com/djgpp/doc/libc/libc_83.html" target="_blank">ceil</a><span class="k2">(</span>y<span class="k2">)</span>

offsetX <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_332.html" target="_blank">fmod</a><span class="k2">(</span>x, <span class="n">1</span><span class="k2">)</span>
offsetY <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_332.html" target="_blank">fmod</a><span class="k2">(</span>y, <span class="n">1</span><span class="k2">)</span>

topRowColour <span class="k3">=</span> colourTopRight<span class="k3">*</span>offsetX <span class="k3">+</span> colourTopLeft<span class="k3">*</span><span class="k2">(</span><span class="n">1</span> <span class="k3">-</span> offsetX<span class="k2">)</span>
bottomRowColour <span class="k3">=</span> colourBottomRight<span class="k3">*</span>offsetX <span class="k3">+</span> colourBottomLeft<span class="k3">*</span><span class="k2">(</span><span class="n">1</span> <span class="k3">-</span> offsetX<span class="k2">)</span>

pixelColour <span class="k3">=</span> bottomRowColour<span class="k3">*</span>offsetY <span class="k3">+</span> topRowColour<span class="k3">*</span><span class="k2">(</span><span class="n">1</span> <span class="k3">-</span> offsetY<span class="k2">)</span>
</pre></div></div><p>
There are potentially some issues with wrapping and texel alignment. I&#39;ve put the lit bit on the top left of each square and the wrapping relates to, for example drawing pixels from the extreme right-hand side of the source image. Bilinear filtering assumes it can always find four colours that surround the location you&#39;re querying, but at some point you go so far right that you have only the two colours to the left and nothing to the right — usually you&#39;ll either wrap around back to the lefthand side or &#39;clamp&#39; values so that you end up with a linear filter on the edges rather than a bilinear one. Exactly how you want to deal with those issues is application specific, if you&#39;re doing anything sufficiently rigourous to require doubles then I&#39;m sure you&#39;ll be able to figure out what you want.</p><p>It will be far from the most speedy implementation, but if you step through the output pixels, scale them to their location in the source then apply the above, you&#39;ll get the number you want. So maybe do that and optimise up from there if speed is an issue? E.g.
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">for</span><span class="k2">(</span><span class="k1">int</span> outputx <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> outputx <span class="k3">&lt;</span> outputwidth<span class="k2">;</span> outputx<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span>
  <span class="k1">for</span><span class="k2">(</span><span class="k1">int</span> outputy <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> outputy <span class="k3">&lt;</span> outputheight<span class="k2">;</span> outputy<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span>
  <span class="k2">{</span>
     <span class="c">// yes, I'm casting too much</span>
     <span class="k1">double</span> sourcex <span class="k3">=</span> <span class="k2">(</span><span class="k1">double</span><span class="k2">)</span>outputx <span class="k3">*</span> <span class="k2">(</span><span class="k1">double</span><span class="k2">)</span>sourcewidth <span class="k3">/</span> <span class="k2">(</span><span class="k1">double</span><span class="k2">)</span>outputwidth<span class="k2">;</span>
     <span class="k1">double</span> sourcey <span class="k3">=</span> <span class="k2">(</span><span class="k1">double</span><span class="k2">)</span>outputy <span class="k3">*</span> <span class="k2">(</span><span class="k1">double</span><span class="k2">)</span>sourceheight <span class="k3">/</span> <span class="k2">(</span><span class="k1">double</span><span class="k2">)</span>outputheight<span class="k2">;</span>

      <span class="k3">&lt;</span>apply above code to get pixelColour&gt;

      let colour at <span class="k2">(</span>outputx, outputy<span class="k2">)</span> <span class="k3">=</span> pixelColour
  <span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Harte)</author>
		<pubDate>Wed, 01 Jul 2009 17:17:33 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If it&#39;s just an array of doubles then what you need is much simpler than my code, since accesing the bitmap data is the complex part (specially doing it in an efficient way). Just change all the code that reads and writes to the bitmap and whenever you find r, g and b values, you just have one in your case (the formulas are the same, but you only apply them to one value). Remove any code wraped inside an #ifdef ALGO_1, since that code is an optimization that would only apply when reading from allegro Bitmaps.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Oscar Giner)</author>
		<pubDate>Wed, 01 Jul 2009 18:03:52 +0000</pubDate>
	</item>
</rss>
