<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://www.newlc.com" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>NewLC - How to Scale Bitmap Faster - Comments</title>
 <link>http://www.newlc.com/forum/how-scale-bitmap-faster</link>
 <description>Comments for &quot;How to Scale Bitmap Faster&quot;</description>
 <language>en</language>
<item>
 <title>Re: How to Scale Bitmap Faster</title>
 <link>http://www.newlc.com/forum/how-scale-bitmap-faster#comment-43488</link>
 <description>&lt;p&gt;Thank you both, alh and miguelbl. Alh, your comments really open my eyes on ways to re-scale bitmaps. And miguelbl, if time allows, i will definitely give it a try to use openGL if the device supports 3d hardware acceleration.&lt;/p&gt;

&lt;p&gt;I dont&#039; really have much experience with dealing with pixels. so I am trying my best to get there. I have avoided using TBitmapUtil and instead use lockheap() and dataAddress(). It give me a improved processing time. But there&#039;s still something I have to figure out. my scaled bitmap is declining... I guess was wrong with the stride... or pixel size. I think i know where... I will post my findings later.&lt;/p&gt;

&lt;p&gt;void CMyEngine::ScaleBitmap(CFbsBitmap&amp; aSrcBmp, CFbsBitmap&amp; aDstBmp)&lt;br /&gt;
	{&lt;br /&gt;
	TSize srcBmpSize = aSrcBmp.SizeInPixels();&lt;br /&gt;
	TSize dstBmpSize = aDstBmp.SizeInPixels();&lt;br /&gt;
	&lt;br /&gt;
	TInt intPart2 = srcBmpSize.iHeight / dstBmpSize.iHeight;&lt;br /&gt;
	TInt fractPart2 = srcBmpSize.iHeight % dstBmpSize.iHeight;&lt;br /&gt;
	TInt e2 = 0;&lt;br /&gt;
	&lt;br /&gt;
	TInt intPart = srcBmpSize.iWidth / dstBmpSize.iWidth;&lt;br /&gt;
	TInt fractPart = srcBmpSize.iWidth % dstBmpSize.iWidth;&lt;br /&gt;
	TInt e = 0;&lt;br /&gt;
	&lt;br /&gt;
	aSrcBmp.LockHeap(ETrue);&lt;br /&gt;
	aDstBmp.LockHeap(ETrue);&lt;br /&gt;
	&lt;br /&gt;
	TUint16* src = (TUint16*) aSrcBmp.DataAddress();&lt;br /&gt;
	TUint16* dst = (TUint16*) aDstBmp.DataAddress();&lt;br /&gt;
	TUint16* origin = src;&lt;br /&gt;
	&lt;br /&gt;
	TInt srcYIndex = 0;&lt;br /&gt;
	for(TInt i = 0; i &lt; dstBmpSize.iHeight; i++)&lt;br /&gt;
		{&lt;br /&gt;
		for(TInt j = 0; j &lt; dstBmpSize.iWidth; j++)&lt;br /&gt;
			{&lt;br /&gt;
			Mem::Copy(dst, src, 2);&lt;br /&gt;
			&lt;br /&gt;
			src += intPart;&lt;br /&gt;
			dst++;&lt;br /&gt;
			&lt;br /&gt;
			e += fractPart;&lt;br /&gt;
			if( e &gt;= dstBmpSize.iWidth)&lt;br /&gt;
				{&lt;br /&gt;
				e -= dstBmpSize.iWidth;&lt;br /&gt;
				src++;&lt;br /&gt;
				}&lt;br /&gt;
			}		&lt;br /&gt;
			&lt;br /&gt;
		srcYIndex += intPart2;&lt;br /&gt;
//		dst = (TUint16*) aDstBmp.DataAddress() + i * dstBmpSize.iWidth;&lt;br /&gt;
		&lt;br /&gt;
		e2 += fractPart2;&lt;br /&gt;
		if(e2 &gt;= dstBmpSize.iHeight)&lt;br /&gt;
			{&lt;br /&gt;
			e2 -= dstBmpSize.iHeight;&lt;br /&gt;
			srcYIndex++;&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		src = origin + srcYIndex * srcBmpSize.iWidth;&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
	aSrcBmp.UnlockHeap();&lt;br /&gt;
	aDstBmp.UnlockHeap();&lt;br /&gt;
	}&lt;/p&gt;</description>
 <pubDate>Thu, 13 Dec 2007 21:45:15 +0100</pubDate>
 <dc:creator>SymbianJunior</dc:creator>
 <guid isPermaLink="false">comment 43488 at http://www.newlc.com</guid>
</item>
<item>
 <title>Re: How to Scale Bitmap Faster</title>
 <link>http://www.newlc.com/forum/how-scale-bitmap-faster#comment-43489</link>
 <description>&lt;p&gt;I found my problem. As discussed in this topic, &lt;a href=&quot;http://&quot; class=&quot;bb-url&quot;&gt;http://newlc.com/topic-17576&lt;/a&gt;, I didn&#039;t call scanLineLength() to find out the number of bytes a scan line in the picture is as I jumped around to pick the pixel I want to copy. Now the scaled bmp looks ok. &lt;/p&gt;</description>
 <pubDate>Thu, 13 Dec 2007 21:44:43 +0100</pubDate>
 <dc:creator>SymbianJunior</dc:creator>
 <guid isPermaLink="false">comment 43489 at http://www.newlc.com</guid>
</item>
<item>
 <title>Re: How to Scale Bitmap Faster</title>
 <link>http://www.newlc.com/forum/how-scale-bitmap-faster#comment-43487</link>
 <description>&lt;p&gt;I would say using openGL is even better &lt;img src=&quot;/sites/all/modules/smileys/packs/example/smile.png&quot; title=&quot;Smiling&quot; alt=&quot;Smiling&quot; /&gt;&lt;br /&gt;
Specially if the image is not changeing.&lt;/p&gt;

&lt;p&gt;Then you should be able to add some bilinear filtering too, without losing too much frame rate, increasing the image quality a lot.&lt;/p&gt;

&lt;p&gt;Though, very few devices have real HW support still, most just use Hybrids SW OpenGL that S60 has licensed.&lt;br /&gt;
Hybrids engine has very good performance for being a SW only implementation, but its not sure it will be faster for this specific usecase.&lt;/p&gt;

&lt;p&gt;Its ofcourse possible to add bilinear filtering to a software DDA routine too, but it slows it down with a factor of at least 10 times.&lt;/p&gt;

&lt;p&gt;And it don&#039;t add that much quality as long as you are constantly moving the image, then you hide a lot of the aliasing, at least if you calculate your roundings right &lt;img src=&quot;/sites/all/modules/smileys/packs/example/smile.png&quot; title=&quot;Smiling&quot; alt=&quot;Smiling&quot; /&gt;&lt;/p&gt;

&lt;p&gt;bi-linear is mostly needed if you are going to scale an image and show it in that size for an extended time. (and then you can pre-calc it and redisplay it)&lt;br /&gt;
&lt;/p&gt;</description>
 <pubDate>Thu, 13 Dec 2007 15:26:43 +0100</pubDate>
 <dc:creator>alh</dc:creator>
 <guid isPermaLink="false">comment 43487 at http://www.newlc.com</guid>
</item>
<item>
 <title>Re: How to Scale Bitmap Faster</title>
 <link>http://www.newlc.com/forum/how-scale-bitmap-faster#comment-43485</link>
 <description>&lt;p&gt;There is also another option almost as good as the ones suggested if you have a HW-accelerated device.&lt;br /&gt;
 You can use openGL to render the image to the screen (if the image changes often, you can feed a texture). &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;</description>
 <pubDate>Thu, 13 Dec 2007 14:23:52 +0100</pubDate>
 <dc:creator>miguelbl</dc:creator>
 <guid isPermaLink="false">comment 43485 at http://www.newlc.com</guid>
</item>
<item>
 <title>Re: How to Scale Bitmap Faster</title>
 <link>http://www.newlc.com/forum/how-scale-bitmap-faster#comment-43462</link>
 <description>&lt;p&gt;In that case, If I were you, I&#039;d take a look at some DDA zooming routines, and zoom directly to the screen.&lt;br /&gt;
You can even kick in rotation in it with almost no extra overhead.&lt;/p&gt;

&lt;p&gt;In a DDA you only have add:s in your inner loop, you calculate all deltas outside it, so it is almost as fast as a straight blit (except that you will always trash the cache when you start rotating, decreasing performance because of this)&lt;/p&gt;

&lt;p&gt;I wouldn&#039;t be suprised if you could get it faster then the (non-scaling) symbian CFbsBitGc:BitBlt if you make sure to match color formats on src and dst &lt;img src=&quot;/sites/all/modules/smileys/packs/example/smile.png&quot; title=&quot;Smiling&quot; alt=&quot;Smiling&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;</description>
 <pubDate>Wed, 12 Dec 2007 16:57:55 +0100</pubDate>
 <dc:creator>alh</dc:creator>
 <guid isPermaLink="false">comment 43462 at http://www.newlc.com</guid>
</item>
<item>
 <title>Re: How to Scale Bitmap Faster</title>
 <link>http://www.newlc.com/forum/how-scale-bitmap-faster#comment-43452</link>
 <description>&lt;p&gt;Hi Alh,&lt;/p&gt;

&lt;p&gt;Thanks for you detailed reply. To answer your concerns. I am doing a zoom in/out on a bitmap. Instead of keeping scaled bitmaps at different zoom levels, I am scaling a portion of the original bitmap per zoom in/out call. That&#039;s where it requires constantly scale.&lt;br /&gt;
 &lt;br /&gt;
I will look into your suggestions and see what I can do to improve my app. Many thanks.&lt;/p&gt;</description>
 <pubDate>Wed, 12 Dec 2007 15:23:02 +0100</pubDate>
 <dc:creator>SymbianJunior</dc:creator>
 <guid isPermaLink="false">comment 43452 at http://www.newlc.com</guid>
</item>
<item>
 <title>Re: How to Scale Bitmap Faster</title>
 <link>http://www.newlc.com/forum/how-scale-bitmap-faster#comment-43449</link>
 <description>&lt;p&gt;Why do you need to constantly rescale?&lt;br /&gt;
Is it possible for you to cache the scaled result and re-use it to save on scaling?&lt;br /&gt;
Scaling is always a heavy operation and those questions need answer first.&lt;/p&gt;

&lt;p&gt;Then, onto making it faster...&lt;/p&gt;

&lt;p&gt;1. Don&#039;t use TBitmapUtils, &lt;br /&gt;
It is very slow, because you will do a lot of unnecessary pixel conversions, and also a lot of unnecessary heap locking.&lt;/p&gt;

&lt;p&gt;2. Generally, avoid any symbian draw calls&lt;br /&gt;
Unfortunately, high performance graphics programming is not symbians strong side.&lt;/p&gt;

&lt;p&gt;3. Go low level&lt;br /&gt;
Use LockHeap, DataAddress and UnlockHeap to get raw access to the pixel buffer in memory.&lt;br /&gt;
This will need more knowledge on pixel formats, and some skill in modifying buffers efficiently.&lt;br /&gt;
The first is available on this forum by searching (or ask me) and the second is available in lots of example code out there, look for games and &quot;democoder&quot; examples from the 90s.&lt;/p&gt;

&lt;p&gt;4. Optimize&lt;br /&gt;
For example, try avoid multiplications in your inner loops, calculate scanline offsets outside it (eg: y*data_stride)&lt;br /&gt;
Your algoritm looks pretty good though on the first look, though I don&#039;t have time to analyse it in detail&lt;/p&gt;

&lt;p&gt;I think your main stumblestone might be pixel conversions going on inside TBitmapUtils when you read out and write back pixels. If the color depth is the same on dst and src, this is ofcourse unnecessary, but TBitmapUtils can&#039;t know this by its design.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;</description>
 <pubDate>Wed, 12 Dec 2007 14:31:35 +0100</pubDate>
 <dc:creator>alh</dc:creator>
 <guid isPermaLink="false">comment 43449 at http://www.newlc.com</guid>
</item>
<item>
 <title>How to Scale Bitmap Faster</title>
 <link>http://www.newlc.com/forum/how-scale-bitmap-faster</link>
 <description>&lt;p&gt;Hi All,&lt;/p&gt;

&lt;p&gt;I want to constantly scale large bitmaps down to a displayable size.&lt;/p&gt;

&lt;p&gt;I have tried drawRect() in CFbsBitGc and it turns out it&#039;s taking too long. I also wrote my own scaling function and it&#039;s no better than drawRect(). My scale function is below.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://www.newlc.com/forum/how-scale-bitmap-faster&quot;&gt;read more&lt;/a&gt;&lt;/p&gt;</description>
 <comments>http://www.newlc.com/forum/how-scale-bitmap-faster#comments</comments>
 <category domain="http://www.newlc.com/forums/2d-3d-graphics">Bitmaps and Graphics</category>
 <pubDate>Tue, 11 Dec 2007 22:28:03 +0100</pubDate>
 <dc:creator>SymbianJunior</dc:creator>
 <guid isPermaLink="false">19786 at http://www.newlc.com</guid>
</item>
</channel>
</rss>
