<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4759034958874637556</id><updated>2011-12-11T05:54:33.980-08:00</updated><title type='text'>Stanislav Vitvitskiy's blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-5578260600524616037</id><published>2010-05-17T08:08:00.000-07:00</published><updated>2010-05-17T08:09:38.447-07:00</updated><title type='text'>JCodec is now standard compliant!</title><content type='html'>&lt;p&gt;JCodec has been tested to decode 43 bit streams provided by
ITU-T ( &lt;a
 href="http://ftp3.itu.int/av-arch/jvt-site/draft_conformance/"&gt;http://ftp3.itu.int/av-arch/jvt-site/draft_conformance/&lt;/a&gt;
) for baseline profile ( &lt;a href="http://jcodec.org/conform.html"&gt;See this page&lt;/a&gt; ).
Every bit stream also contains a reference YUV sequence that the
compliant decoder is expected to produce. The bit streams are crafted to
test the behavior of the decoder in many different scenarios including
unusual ones.&lt;/p&gt;
&lt;p&gt;However &amp;quot;there is no official H.264/AVC compliance test ...
specified by either ITU or ISO. The conformance tests on the FTP site
are very basic and do not test all possible decoding modes. The
conformance testing gap has been filled by (at least two) commercial
products. One of them is provided by Fraunhofer HHI&amp;quot;. So if anyone
has access to the test suite of the commercial products and would agree
to test JCodec against it I would very much appreciate!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-5578260600524616037?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/5578260600524616037/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=5578260600524616037' title='0 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/5578260600524616037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/5578260600524616037'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2010/05/jcodec-is-now-standard-compliant.html' title='JCodec is now standard compliant!'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-8171571338373512658</id><published>2010-05-05T15:02:00.000-07:00</published><updated>2010-05-07T01:06:58.572-07:00</updated><title type='text'>That's how jcodec works!</title><content type='html'>&lt;![if gte IE 7]&gt;
&lt;iframe src="http://jcodec.org/player.html" width="550" height="400" frameborder="0"&gt;&lt;/iframe&gt;
&lt;![endif]&gt;
&lt;!--[if lt IE 7]&gt;
&lt;p style="color: red; font-weight: 800;"&gt;Your browser is too old to display this clip. Try downloading firefox from &lt;a href="http://getfirefox.com"&gt;getfirefox.com&lt;/a&gt;&lt;/p&gt;
&lt;![endif]--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-8171571338373512658?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/8171571338373512658/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=8171571338373512658' title='4 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/8171571338373512658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/8171571338373512658'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2010/05/thats-how-jcodec-works.html' title='That&apos;s how jcodec works!'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-2706142684465209957</id><published>2010-04-14T00:44:00.000-07:00</published><updated>2010-04-14T00:53:07.638-07:00</updated><title type='text'>Source code of Samsung Android platforms</title><content type='html'>For those who are curious, the source code of Samsung Android platforms is here:

&lt;a href="http://opensource.samsungmobile.com/index.jsp"&gt;http://opensource.samsungmobile.com/index.jsp&lt;/a&gt;

&lt;br/&gt;&lt;br/&gt;
SHW-A180S, SHW-A160S SPH-W9705, SCH-W890, SPH-W9600, SPH-W9500, SCH-I899, SCH-W940, SPH-W9300, SCH-W930, SPH-W9350, Dolfin v1.5-using models, SPH-W9000, SPH-W9050, SCH-W900, GT-I6410, GT-I6410, GT-I6410, GT-I5700, SGH-T939, SGH-A797, SPH-M900, GT-I8320, SCH-W820, SPH-W8200, YP-R0, YP-R1, GT-I7500, SPH-M560, SCH-W850, SPH-W8500, SCH-i859, SWT-W100K, SCH-i839, SGH-i858, SCH-i819

&lt;br/&gt;
&lt;br/&gt;
Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-2706142684465209957?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/2706142684465209957/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=2706142684465209957' title='0 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/2706142684465209957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/2706142684465209957'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2010/04/source-code-of-samsung-android.html' title='Source code of Samsung Android platforms'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-1981060663588027409</id><published>2010-04-12T04:04:00.000-07:00</published><updated>2010-04-12T04:07:26.300-07:00</updated><title type='text'>For those curious of you</title><content type='html'>The very first java specification:
&lt;a href="http://www.me.umn.edu/~shivane/blogs/cafefeed/resources/14-jun-2007/OakSpec0.2.zip"&gt;http://www.me.umn.edu/~shivane/blogs/cafefeed/resources/14-jun-2007/OakSpec0.2.zip&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-1981060663588027409?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/1981060663588027409/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=1981060663588027409' title='0 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/1981060663588027409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/1981060663588027409'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2010/04/for-those-curious-of-you.html' title='For those curious of you'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-1439422934290504013</id><published>2010-04-01T09:49:00.000-07:00</published><updated>2010-04-01T09:50:50.565-07:00</updated><title type='text'>Home, sweet home</title><content type='html'>As of today &lt;a href="http://jcodec.org"&gt;jcodec&lt;/a&gt; has it's own web site. Welcome &lt;a href="http://jcodec.org"&gt;jcodec.org&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-1439422934290504013?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/1439422934290504013/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=1439422934290504013' title='2 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/1439422934290504013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/1439422934290504013'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2010/04/home-sweet-home.html' title='Home, sweet home'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-9080202736256744701</id><published>2010-03-03T13:45:00.000-08:00</published><updated>2010-03-03T13:46:50.137-08:00</updated><title type='text'>Here comes a color</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Tlxv57Y8NtU/S47Yv0WLRcI/AAAAAAAAAFA/UGN9C3kJ6TY/s1600-h/Picture3.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 238px;" src="http://3.bp.blogspot.com/_Tlxv57Y8NtU/S47Yv0WLRcI/AAAAAAAAAFA/UGN9C3kJ6TY/s320/Picture3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5444527315554616770" /&gt;&lt;/a&gt;
Color done, artifacts fixed, tested on 3000 frames sequence. All perfect!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-9080202736256744701?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/9080202736256744701/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=9080202736256744701' title='4 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/9080202736256744701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/9080202736256744701'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2010/03/here-comes-color.html' title='Here comes a color'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Tlxv57Y8NtU/S47Yv0WLRcI/AAAAAAAAAFA/UGN9C3kJ6TY/s72-c/Picture3.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-8946404591716460143</id><published>2010-02-12T17:46:00.000-08:00</published><updated>2010-03-10T15:19:53.138-08:00</updated><title type='text'>Today jcodec selebrates it's first frame</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Tlxv57Y8NtU/S3YFDh_3i_I/AAAAAAAAAEc/ja2hadCaaI0/s1600-h/javcodec_sm.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 155px;" src="http://2.bp.blogspot.com/_Tlxv57Y8NtU/S3YFDh_3i_I/AAAAAAAAAEc/ja2hadCaaI0/s320/javcodec_sm.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5437539158320450546" /&gt;&lt;/a&gt;
It's been a tough time, but I've finally managed to get the very first frame out of my pure java h264 video decoder.

Meet &lt;a href="http://code.google.com/p/jcodec/"&gt;jcodec&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-8946404591716460143?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/8946404591716460143/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=8946404591716460143' title='0 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/8946404591716460143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/8946404591716460143'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2010/02/today-javcodec-selebrates-its-first.html' title='Today jcodec selebrates it&apos;s first frame'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Tlxv57Y8NtU/S3YFDh_3i_I/AAAAAAAAAEc/ja2hadCaaI0/s72-c/javcodec_sm.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-8815960795952846710</id><published>2010-01-27T16:24:00.001-08:00</published><updated>2010-01-27T16:25:30.784-08:00</updated><title type='text'>Pixels don't come easy to me ...</title><content type='html'>Today I finally got the very first pixels out of my pure Java H264 video decoder.
Today is a wonderful day!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-8815960795952846710?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/8815960795952846710/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=8815960795952846710' title='0 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/8815960795952846710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/8815960795952846710'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2010/01/pixels-don.html' title='Pixels don&apos;t come easy to me ...'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-9013113457586200715</id><published>2009-10-21T07:01:00.000-07:00</published><updated>2009-10-21T07:36:52.791-07:00</updated><title type='text'>SSE vector operations in GCC</title><content type='html'>Thanks to GCC vector types one can do SSE vector operations without having to write any assembly.

The below code snippet:
&lt;pre name="code" class="javascript"&gt;
#include &amp;lt;stdio.h&amp;gt;

typedef int v4si __attribute__ ((mode(V4SI)));

int main(int argc, char** argv) {


     v4si a[10], b[10], c[10];

        for(int i = 0; i &lt; 10; i++) {
     c[i] = a[i] + b[i];
}

}

&lt;/pre&gt;

translates into the following assembly:

&lt;pre name="code" class="c"&gt;
 movdqa  (%eax), %xmm1
 ...   
 movdqa  (%eax), %xmm0
 paddd   %xmm1, %xmm0

&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-9013113457586200715?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/9013113457586200715/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=9013113457586200715' title='0 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/9013113457586200715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/9013113457586200715'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2009/10/sse-vector-operations-in-gcc.html' title='SSE vector operations in GCC'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-8335209073752560973</id><published>2009-10-21T04:54:00.000-07:00</published><updated>2009-10-21T04:57:45.710-07:00</updated><title type='text'>Linux profiling experience</title><content type='html'>After rambling around for a while I finally settled on Valgrind with kcachegdind GUI for profiling my C/C++ code under Linux.

On my Ubuntu box:

&lt;pre&gt;
sudo apt-get install valgrind
sudo apt-get install kcachegrind
valgrind --tool=callgrind &lt;your program&gt;
kcachegrind
&lt;/pre&gt;

That's it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-8335209073752560973?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/8335209073752560973/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=8335209073752560973' title='0 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/8335209073752560973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/8335209073752560973'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2009/10/linux-profiling-experience.html' title='Linux profiling experience'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-7232286378691640025</id><published>2009-05-08T14:35:00.000-07:00</published><updated>2009-05-08T14:59:22.215-07:00</updated><title type='text'>Some XULRunner traps on Mac OS X</title><content type='html'>Recently I've been fighting for quite a while with my XUL (Gecko runtime aka GRE) application on Mac OS X trying to make is 'speak' to java via LiveConnect.

I had couple of problems which other people might also run into:
&lt;ul&gt;
&lt;li&gt;I accidentally downloaded a PowerPC version of XULRunner to my Intel Mac. While it runs perfectly well (thanks to &lt;a href="http://www.apple.com/rosetta/"&gt;Rosetta&lt;/a&gt;) it implies that java is also a PowerPC version. To check which platform your xulrunner supports simply type:
&lt;pre name="code" class="javascript"&gt;
file /Library/Frameworks/XUL.framework/Versions/Current/xulrunner-bin
&lt;/pre&gt;
The output should contain something except PowerPC ('ppc').
&lt;/li&gt;
&lt;li&gt;You may still experience problems connecting to java due to outdated java plugin. In this case you may wish to download &lt;a href="http://javaplugin.sourceforge.net/"&gt;Java Embedding Plugin&lt;/a&gt; which utilizes Apple's Safari plugin to do the job.&lt;/li&gt;
&lt;li&gt;Because XULRunner is distributed as x86 32 bit binary you'll have to use an appropriate java compiled for x86 32 bit. This is either default Leopard Sun JDK 1.5.x or &lt;a href="http://landonf.bikemonkey.org/static/soylatte/"&gt;Soylatte&lt;/a&gt; ( an independent OpenJDK port for OS X).&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-7232286378691640025?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/7232286378691640025/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=7232286378691640025' title='2 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/7232286378691640025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/7232286378691640025'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2009/05/some-xulrunner-traps-on-mac-os-x.html' title='Some XULRunner traps on Mac OS X'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-751698975935823174</id><published>2009-04-30T14:24:00.000-07:00</published><updated>2009-05-05T02:50:06.056-07:00</updated><title type='text'>Calling java from XUL applications</title><content type='html'>&lt;a href="https://developer.mozilla.org/en/XULRunner"&gt;XULRunner&lt;/a&gt; is a technology from Mozilla that allows to create cross-platform GUI applications just as easy as a websites.

Today I was trying to use my java libraries inside of a XUL application. This is basically to be able to load a jar file and call java functions with my javascript code.

It turns out that the only ( and the best ) way to accomplish this is by using &lt;a href="https://jdk6.dev.java.net/plugin2/liveconnect/"&gt;LiveConnect&lt;/a&gt;, a feature of java plugin that allows to 'talk' to java. LiveConnect among other things is responsible for communication with java applets.

With LiveConnect one can instanciate arbitrary java class and use it in javascript. Any java objects returned from method calls will be accessible in javascript as well as any javascript objects passed to java methods will be accessible in java. To achieve this effect LiveConnect does two-way wrapping of objects, i.e. it wraps java object with javascript and the other way around. 

More precisely, to instanciate a JVM object simply do this:
&lt;pre name="code" class="javascript"&gt;
var javaObject = new java.lang.String('Hello');
&lt;/pre&gt;
So to load classes from a library simply instanciate a classloader and then use it to instanciate the classes. Something like this:
&lt;pre name="code" class="javascript"&gt;
  function getAppPath(appName) {
    var chromeRegistry = Components
      .classes["@mozilla.org/chrome/chrome-registry;1"]
      .getService(Components.interfaces.nsIChromeRegistry);
            
    var uri =
      Components.classes["@mozilla.org/network/standard-url;1"]
        .createInstance(Components.interfaces.nsIURI);
    
    uri.spec = "chrome://" + appName + "/content/";
    
    var path = chromeRegistry.convertChromeURL(uri);
    if (typeof(path) == "object") {
        path = path.spec;
    }
    
    path = path.substring(0, path.indexOf("/chrome/") + 1);
    
    return path;
  };

  var basePath = getAppPath('myapp');
  var url = new java.net.URL(basePath + 'java/my.jar');
  var cl = new java.net.URLClassLoader( [ url ] );
  
  var aClass = java.lang.Class.forName("com.stan.XULDemo", true, cl);

  var inst = aClass.newInstance();

  // Calling 'sum' function from java
  var a = inst.sum(2, 3); 
  alert(a);  // Will alert '5'

  // A function which we'll pass to java
  // and have java call it later with a parameter
  var callback = function(str) {
    alert(str);
  };

  inst.callMeLater(callback, 'test');
&lt;/pre&gt;

The code of com.stan.XULDemo.java will be the following:
&lt;pre name="code" class="java"&gt;
package com.stan;

public calss XULDemo {
  public int sum(int a, int b) {
    return a + b;
  }
  
  public void callMeLater(final JSObject func, final String text) {
    new Thread() {
      public void run() {
        try {
          Thread.sleep(5000);  // Sleep 5 seconds
        } catch(Exception e) { }
        
        // We are passed a javascript Function Object 
        // which has method 'call' used to actually call the
        // function. The first parameter is 'this',
        // followed by a set
        // of actual function parameters
        func.call("call", new Object[] { null, text });
      }
    }.start();
  }
}
&lt;/pre&gt;

This works out of the box with XULRunner.

Note. Currently there are troubles with LiveConnect 1.9 on Mac (jdk 1.6 u3) which I am looking at right now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-751698975935823174?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/751698975935823174/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=751698975935823174' title='7 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/751698975935823174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/751698975935823174'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2009/04/calling-java-from-xul-applications.html' title='Calling java from XUL applications'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4759034958874637556.post-960504069717614079</id><published>2008-12-25T07:05:00.000-08:00</published><updated>2009-05-05T02:55:59.923-07:00</updated><title type='text'>Multipart post in Ruby</title><content type='html'>&lt;div style="font-family: arial;"&gt;Uploading a file to a server is a common task in web-development practice. It requires you to create a special HTML form with enctype set to 'multipart/form-data' and include an input of type 'file' into it.&lt;/div&gt;

&lt;div style="font-family: arial;"&gt;However sometime you want to upload a file to some third-party service from your Ruby script on background. For this you'll need to properly construct the multipart POST request and send it out via Ruby net/http library.&lt;/div&gt;

&lt;div style="font-family: arial;"&gt;After playing a bit I came up with the following class. A very strong advantage of it is that it works well with big files ( such as videos ).&lt;/div&gt;

&lt;pre name="code" class="ruby"&gt;
class Multipart
 
  def initialize( file_names )
    @file_names = file_names
  end
 
  def post( to_url )
    boundary = '----RubyMultipartClient' + rand(1000000).to_s + 'ZZZZZ'
   
    parts = []
    streams = []
    @file_names.each do |param_name, filepath|
      pos = filepath.rindex('/')
      filename = filepath[pos + 1, filepath.length - pos]
      parts &lt;&lt; StringPart.new ( "--" + boundary + "\r\n" +
      "Content-Disposition: form-data; name=\"" + param_name.to_s + "\"; filename=\"" + filename + "\"\r\n" +
      "Content-Type: video/x-msvideo\r\n\r\n")
      stream = File.open(filepath, "rb")
      streams &lt;&lt; stream
      parts &lt;&lt; StreamPart.new (stream, File.size(filepath))
    end
    parts &lt;&lt; StringPart.new ( "\r\n--" + boundary + "--\r\n" )
   
    post_stream = MultipartStream.new( parts )
   
    url = URI.parse( to_url )
    req = Net::HTTP::Post.new(url.path)
    req.content_length = post_stream.size
    req.content_type = 'multipart/form-data; boundary=' + boundary
    req.body_stream = post_stream
    res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }

    streams.each do |stream|
      stream.close();
    end
   
    res
  end
 
end

class StreamPart
  def initialize( stream, size )
    @stream, @size = stream, size
  end
 
  def size
    @size
  end
 
  def read ( offset, how_much )
    @stream.read ( how_much )
  end
end

class StringPart
  def initialize ( str )
    @str = str
  end
 
  def size
    @str.length
  end
 
  def read ( offset, how_much )
    @str[offset, how_much]
  end
end

class MultipartStream
  def initialize( parts )
    @parts = parts
    @part_no = 0;
    @part_offset = 0;
  end
 
  def size
    total = 0
    @parts.each do |part|
      total += part.size
    end
    total
  end
 
  def read ( how_much )
   
    if @part_no &gt;= @parts.size
      return nil;
    end
   
    how_much_current_part = @parts[@part_no].size - @part_offset
   
    how_much_current_part = if how_much_current_part &gt; how_much
      how_much
    else
      how_much_current_part
    end
   
    how_much_next_part = how_much - how_much_current_part
   
    current_part = @parts[@part_no].read(@part_offset, how_much_current_part )

    if how_much_next_part &gt; 0
      @part_no += 1
      @part_offset = 0
      next_part = read ( how_much_next_part  )
      current_part + if next_part
        next_part
      else
        ''
      end
    else
      @part_offset += how_much_current_part
      current_part
    end
  end
end

&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4759034958874637556-960504069717614079?l=stanislavvitvitskiy.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://stanislavvitvitskiy.blogspot.com/feeds/960504069717614079/comments/default' title='Дописати коментарі'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4759034958874637556&amp;postID=960504069717614079' title='0 коментарі(в)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/960504069717614079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4759034958874637556/posts/default/960504069717614079'/><link rel='alternate' type='text/html' href='http://stanislavvitvitskiy.blogspot.com/2008/12/multipart-post-in-ruby.html' title='Multipart post in Ruby'/><author><name>Stanislav Vitvitskiy</name><uri>http://www.blogger.com/profile/07534939991293903525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
