<?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>Moodstocks</title>
	<atom:link href="http://www.moodstocks.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.moodstocks.com</link>
	<description>We bridge the physical and digital worlds</description>
	<lastBuildDate>Fri, 18 May 2012 14:27:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Hacking the Elections with Voxe and Moodstocks</title>
		<link>http://www.moodstocks.com/2012/03/22/hacking-the-elections-with-voxe-and-moodstocks/</link>
		<comments>http://www.moodstocks.com/2012/03/22/hacking-the-elections-with-voxe-and-moodstocks/#comments</comments>
		<pubDate>Thu, 22 Mar 2012 15:45:56 +0000</pubDate>
		<dc:creator>cedric</dc:creator>
				<category><![CDATA[Developers]]></category>
		<category><![CDATA[Moodstocks]]></category>
		<category><![CDATA[Moodstocks SDK]]></category>
		<category><![CDATA[Hack]]></category>
		<category><![CDATA[le camping]]></category>
		<category><![CDATA[Voxe]]></category>

		<guid isPermaLink="false">http://www.moodstocks.com/?p=3945</guid>
		<description><![CDATA[As you probably know we, at Moodstocks, are fond of hackathons could it be as a sponsor (fresh beers or whatever!), platform provider or participants! That is why we could not have missed this Hack The Elections Paris-based hackathon organized by Voxe -World&#8217;s Platform for Politics, last week-end at Le Camping! Participants &#8211; made of developers, designers and citizens, were [...]]]></description>
			<content:encoded><![CDATA[<p>As you probably know we, at Moodstocks, are <a title="Hack Le Camping" href="http://hacklecamping.wordpress.com/">fond</a> <a title="Foursquare round-the-clock Hackathon" href="http://blog.foursquare.com/2011/08/17/announcing-the-round-the-clock-round-the-world-foursquare-hackathon/">of</a> <a title="Hack Day Paris" href="http://hackdayparis.org/">hackathons</a> could it be as a sponsor (fresh beers or whatever!), platform provider or participants! That is why we could not have missed this <a title="Hack The Elections" href="http://checkthis.com/bg5g">Hack The Elections</a> Paris-based hackathon organized by <a href="http://voxe.org/">Voxe</a> -World&#8217;s Platform for Politics, last week-end at <a href="http://www.lecamping.org/">Le Camping</a>!</p>
<p>Participants &#8211; made of developers, designers and citizens, were asked to leverage the <a title="Voxe API" href="http://voxe.org/platform">Voxe data API</a> and build a smart app aiming at helping people choose their candidate the clever way for the <a href="http://en.wikipedia.org/wiki/French_presidential_election,_2012">French presidential election, 2012</a>.</p>
<h2>Brainstorm</h2>
<p>On my own I had no predefined idea at pitch time. Keeping in mind the <a href="http://www.avc.com/a_vc/2010/12/the-smartphone-explosion.html">smartphone explosion</a> I started brainstorming around 2 simple facts:</p>
<ul>
<li>• there is a huge amount of political propositions among the set of candidates: at the time of writing <a href="http://voxe.org/">Voxe</a> references 1500+ propositions. This makes it hard for many of us to take time to read, understand and get an opinion on them,</li>
<li>• on a daily basis, until the election D-day, we will go through the candidate official posters as we will commute to work &#8211; and this could really act as a kind of daily reminder.</li>
</ul>
<p>&nbsp;</p>
<p>So I thought it would be great if I could be provided with a <strong>random proposition</strong> each time I encounter the poster of a candidate &#8211; think of it as a kind of <em>one proposition a day</em>. And it would be cool too if I could record at that time if I agree or disagree with this precise proposition: from day to day, cumulating these <strong>small votes</strong> would lead to a good evaluation of what is my <em>real</em> favorite candidate!</p>
<h2>Mashup</h2>
<p>Such a concept was an ideal use case to leverage both Voxe and Moodstocks plaftorms since:</p>
<ul>
<li>• <a href="http://voxe.org/">Voxe</a> provides all the required data via its <a href="http://voxe.org/platform">API</a> from candidates&#8217; propositions (of course) to topics and avatars,</li>
<li>• the <a href="https://github.com/Moodstocks/moodstocks-sdk">Moodstocks SDK</a> is able to identify any candidate poster via the smartphone camera and makes it possible to display related content (here a random proposition) and actions (here vote buttons) directly in overlay of the video capture.</li>
</ul>
<p style="text-align: center;"><a href="http://www.moodstocks.com/wp-content/uploads/2012/03/voxe-moodstocks.png"><img class="aligncenter size-full wp-image-4030" title="voxe-moodstocks" src="http://www.moodstocks.com/wp-content/uploads/2012/03/voxe-moodstocks.png" alt="" width="480" height="162" /></a></p>
<p>I then found a name for the app &#8211; <strong>Voxometre</strong>, a few fords to depict it &#8211; <em>my very own citizen remote control</em>, and started the technical design &amp; implementation focusing on the iOS platform.</p>
<h2>Implementation</h2>
<p>To me such an application had to follow the <a title="serverless programming" href="http://msnrs.posterous.com/serverless-programming">serverless programming</a> principle (i.e. <strong>full client-side </strong>app) since:</p>
<ul>
<li>• the app has no sharing or social features: each small vote made on the random propositions is personal and has to be stored directly on the client. There is no need to centralize this data on the server-side,</li>
<li>• it is a mashup app that consumes all its data from external APIs,</li>
<li>• it is important that the app keeps its data available locally to maximize the user experience via real-time interactions at scanning time (i.e. zero network latency to fetch the data).</li>
</ul>
<p>&nbsp;</p>
<p>So the main topics I had to focus on were:</p>
<ul>
<li>• generating the <strong>pre-defined data</strong> and <strong>assets</strong>: I have written some scripts to pre-fetch the data that will not change from Voxe API (candidacy IDs, candidate names, avatars, main tags, etc) and embed these PNG-s and custom JSON directly within the app,</li>
<li>• designing the <strong>data synchronization</strong> phase: the goal was to trigger at cold start the Moodstocks sync (to retrieve the image signatures) and write some logic to fetch and store the whole set of propositions by calling the <a title="Voxe propositions HTTP API" href="http://voxe.org/platform/endpoints/propositions">search propositions by candidacyID HTTP API</a> provided by Voxe,</li>
<li>• choosing an <strong>embedded database</strong> and defining the <strong>data model</strong>: since we need to store and persist the set of propositions plus the votes made by the end user on the client, I had to use an embedded database. To make sure things were fun enough (!) I decided to use <a title="Redisk Github repository" href="https://github.com/Moodstocks/redisk">Redisk</a> &#8211; the not-so-stable-nor-production-ready Redis-API-compatible embedded database written in C I had co-created with <a href="http://twitter.com/pchapuis">Pierre</a> at the former <a title="Hack Day Paris" href="http://hackdayparis.org/">Hack Day Paris</a> hackathon last november,</li>
<li>• implementing the <strong>overlay</strong> made of the proposition &amp; related tag (as info) plus the votes up / down buttons (as actions).</li>
</ul>
<p>&nbsp;</p>
<p>Being able to use a <a title="Redis commands" href="http://redis.io/commands">Redis-like API</a> on the client-side was pretty handy since it offers simple and convenient data structures to achieve our job. Below is an overview of the (<span style="text-decoration: underline;">very</span>) simple data model:</p>
<div><em><a href="http://www.moodstocks.com/wp-content/uploads/2012/03/voxometre-redis.png"><img class="aligncenter size-full wp-image-4011" title="voxometre-redis" src="http://www.moodstocks.com/wp-content/uploads/2012/03/voxometre-redis.png" alt="" width="639" height="220" /></a></em></div>
<div></div>
<p>Propositions values are stored in raw JSON even if we could have used Redis hashes to store them unserialized. The key format allows to easily find a random proposition by filtering the set of propositions for a candidate via key forward matching.</p>
<p>A set is used to record every proposition that has been voted.</p>
<p>At last the INCR command is used to bump the votes counters per candidate.</p>
<h2>Design</h2>
<p>Then it was time to style the app! I worked with <a title="Aymeric Gallissot" href="http://aymericgallissot.fr/">Aymeric</a> that did a great job at choosing a color theme, designing a logo, creating styled buttons and producing a keynote for the <a href="http://www.slideshare.net/plougy/voxometre">final presentation</a> (feel free to browse these slides for some more details and screenshots).</p>
<p style="text-align: center;"><a href="http://www.moodstocks.com/wp-content/uploads/2012/03/voxometre-logo.png"><img class="aligncenter size-full wp-image-4029" title="voxometre-logo" src="http://www.moodstocks.com/wp-content/uploads/2012/03/voxometre-logo.png" alt="" width="320" height="356" /></a></p>
<p style="text-align: left;"><div class="uds-divider"><a href="#">Top</a></div></p>
<p style="text-align: left;">Once <a href="https://twitter.com/#!/deltheil/status/181466067703570432">again</a> I would like to thank the <a href="http://voxe.org/about/team">Voxe team</a> for the great work they have made organizing this event! Also congrats to <a href="http://twitter.com/pchapuis">Pierre</a> and his team for their <a href="http://democrazy.fr/">Democrazy</a> project!</p>
<p style="text-align: left;">Stay tuned until the next April, 3rd since we will present the project for this <a href="http://www.mash-up.fr/actualite/mash-up-birthday-3-avril/">Mash Up Birthday event</a>!</p>
<p style="text-align: left;">[<strong>UPDATE</strong>] We have now a <a title="Voxomètre" href="http://voxometre.com/">landing page</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moodstocks.com/2012/03/22/hacking-the-elections-with-voxe-and-moodstocks/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ice Cream Sandwich: why native code support sucks.</title>
		<link>http://www.moodstocks.com/2012/03/20/ice-cream-sandwich-why-native-code-support-sucks/</link>
		<comments>http://www.moodstocks.com/2012/03/20/ice-cream-sandwich-why-native-code-support-sucks/#comments</comments>
		<pubDate>Tue, 20 Mar 2012 09:31:48 +0000</pubDate>
		<dc:creator>Maxime Brenon</dc:creator>
				<category><![CDATA[Developers]]></category>
		<category><![CDATA[Moodstocks SDK]]></category>

		<guid isPermaLink="false">http://www.moodstocks.com/?p=3889</guid>
		<description><![CDATA[You can ask any mobile developer: the major disadvantage of developing on Android is the number of different devices you have to support. You have to handle different sizes of screen, different hardware, and a large range of Android versions evolving so fast that ensuring backward compatibility is close to impossible. And if that was [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">You can ask any mobile developer: the major disadvantage of developing on Android is the number of different devices you have to support. You have to handle different sizes of screen, different hardware, and a large range of Android versions evolving so fast that ensuring backward compatibility is close to impossible. And if that was not enough, you sometimes have to deal with bugs&#8230; in Android itself. The latest release, <strong>Ice Cream Sandwich</strong> (ICS), was not an exception to this rule, and did not fail to surprise us with a quite tricky and unpleasant bug.</p>
<p style="text-align: center"><a href="http://www.moodstocks.com/wp-content/uploads/2012/03/Android-Ice-Cream-Sandwich-logo1.jpg"><img class="alignnone size-medium wp-image-4151" src="http://www.moodstocks.com/wp-content/uploads/2012/03/Android-Ice-Cream-Sandwich-logo1-300x201.jpg" alt="" width="300" height="201" /></a></p>
<p> Before going on to the bug in itself, let us give a little context on how it happened. We designed the <a title="Moodstocks SDK on Github" href="https://github.com/Moodstocks/moodstocks-sdk" target="_blank">Moodstocks SDK</a> as a C library and we ported it on iOS then Android thanks to the <a title="Android NDK" href="http://developer.android.com/sdk/ndk/index.html" target="_blank">Android Native Development Kit</a> (NDK). For performance reasons, we decided to support only ARMv7 devices (non-ARMv7 devices being mainly older devices), and cross-compiled our library so that the non-ARMv7 version would only return errors to inform the user that his/her device was not compatible.</p>
<h2 style="text-align: justify">Bug</h2>
<p style="text-align: justify"><div class="uds-divider"><a href="#">Top</a></div></p>
<p style="text-align: justify">Everything went perfectly well until this terrible day of March 2012, when one of our developers informed us that his brand new Samsung Galaxy Nexus running ICS told him that it was not compatible with our SDK. Even worse: after a few tests, he determined that it worked like a charm if he did not bundle too many resources with his app (animation xml&#8217;s, graphical resources, etc&#8230;), and suddenly decided to become incompatible if he bundled more than 8 resources. Yes, you heard me right: apparently, one of the latest and most powerful smartphones available, running the latest version of Android on its dual-core 1.5GHz ARMv7 processor, chose the most absurd and unrelated reason to start thinking of itself as a 3-year-old ARMv6 device.</p>
<p style="text-align: justify">Let&#8217;s first give a little example of what <strong>theoretically</strong> happens when you cross-compile a native library for both these architectures and run it on an Android device. Using the NDK, let&#8217;s build a simple C library containing this function, cross-compiled for ARMv7 and non-ARMv7 architectures:</p>
<p style="text-align: justify"><div id="gist-2119560" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kt">int</span> </div><div class='line' id='LC2'><span class="nf">Java_com_my_namespace_MyClass_MyNativeFunction</span></div><div class='line' id='LC3'><span class="p">(</span><span class="n">JNIEnv</span> <span class="o">*</span><span class="n">env</span><span class="p">,</span> <span class="n">jobject</span> <span class="n">obj</span><span class="p">)</span> <span class="p">{</span></div><div class='line' id='LC4'><span class="cp">#ifdef __ARM_V7__</span></div><div class='line' id='LC5'>&nbsp;&nbsp;<span class="k">return</span> <span class="mi">1</span><span class="p">;</span></div><div class='line' id='LC6'><span class="cp">#else</span></div><div class='line' id='LC7'>&nbsp;&nbsp;<span class="k">return</span> <span class="mi">0</span><span class="p">;</span></div><div class='line' id='LC8'><span class="cp">#endif</span></div><div class='line' id='LC9'><span class="p">}</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2119560/6380115429a0c72d550f48444a665dac6b393832/example.c" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2119560#file_example.c" style="float:right;margin-right:10px;color:#666">example.c</a>
            <a href="https://gist.github.com/2119560">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p style="text-align: justify">This will result in two files: <em>/lib/armeabi-v7a/libfoo.so</em> compiled for ARMv7 devices, and <em>/lib/armeabi/libfoo.so</em> for non-ARMv7 devices. Let&#8217;s write the corresponding Java class:</p>
<p style="text-align: justify"><div id="gist-2111490" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">my</span><span class="o">.</span><span class="na">namespace</span><span class="o">;</span></div><div class='line' id='LC2'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyClass</span> <span class="o">{</span></div><div class='line' id='LC3'>&nbsp;&nbsp;<span class="kd">static</span> <span class="o">{</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">loadLibrary</span><span class="o">(</span><span class="s">&quot;foo&quot;</span><span class="o">);</span></div><div class='line' id='LC5'>&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC6'>&nbsp;&nbsp;<span class="kd">public</span> <span class="kd">native</span> <span class="kt">int</span> <span class="nf">MyNativeFunction</span><span class="o">();</span></div><div class='line' id='LC7'><span class="o">}</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2111490/bbdfe492c1eebd4aaf9fc5a8ab0ff44580c53b0a/example.java" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2111490#file_example.java" style="float:right;margin-right:10px;color:#666">example.java</a>
            <a href="https://gist.github.com/2111490">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p style="text-align: justify">When you call this class in Java, the <em>System.loadLibrary</em> function will check your device, and decide which of the two libraries it will load and use at runtime. And, as expected, this function will return 1 on any ARMv7 device, and 0 otherwise.</p>
<h2 style="text-align: justify">Workaround</h2>
<p style="text-align: justify"><div class="uds-divider"><a href="#">Top</a></div></p>
<p style="text-align: justify">That was for theory. Because in practice, and as explained in <a href="https://groups.google.com/forum/?fromgroups#!topic/android-ndk/N8FLjvM81pg/discussion" target="_blank">this thread</a>, ICS developers accidentally let this <a title="Galaxy Nexus 4.0.2 uses armeabi native code when both armeabi and armeabi-v7a is included in apk, resulting in poor performance on running native code" href="http://code.google.com/p/android/issues/detail?id=25321">functionality go rogue on Android 4.0.1 &#8211; 4.0.3</a>: when crawling the application&#8217;s apk file looking for the right version of the library to use, ICS &#8220;forgets&#8221; that it found an ARMv7 version and choses the non-ARMv7 version instead! Luckily for us, they provide this quite ugly but useful tip:</p>
<p style="text-align: justify"><em>&#8220;ensure that the armeabi-v7a [i.e. ARMv7] binaries are packaged _after_ the armeabi [i.e. non-ARMv7] ones in the final .apk. This is not trivial, but one way to do it is remove the armeabi-v7a files from the package, then add them back, manually.&#8221;</em></p>
<p style="text-align: justify">OK, it looks quite annoying, but at least it shows some coherency with the fact that adding resources could mess up with our SDK, as adding files in an archive does not necessarily preserve the files order. We thus started testing this workaround: after all, the Android SDK contains a small tool called <strong><em>aapt</em></strong> made especially to manipulate apk files. Let&#8217;s try what is suggested:</p>
<p style="text-align: justify"><div id="gist-2115397" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>$ aapt list MyApp.apk                               //shows the content of the apk, we shorten it to our libs only:</div><div class='line' id='LC2'>&gt; lib/armeabi/libfoo.so</div><div class='line' id='LC3'>&gt; lib/armeabi-v7a/libfoo.so</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'>$ jar xf MyApp.apk                                  //extract</div><div class='line' id='LC6'>$ aapt remove MyApp.apk lib/armeabi-v7a/libfoo.so   //remove the ARMv7 lib</div><div class='line' id='LC7'>$ aapt add MyApp.apk lib/armeabi-v7a/libfoo.so      //put it back</div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'>$ aapt list MyApp.apk                               //check result</div><div class='line' id='LC10'>&gt; lib/armeabi/libfoo.so</div><div class='line' id='LC11'>&gt; libfoo.so</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2115397/c1ad3d1891f7fe15be122331cd92e78c43bdbeb0/aapt" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2115397#file_aapt" style="float:right;margin-right:10px;color:#666">aapt</a>
            <a href="https://gist.github.com/2115397">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p style="text-align: justify">See the problem here? The file was added back, but not within the right folder. Let&#8217;s have a look at the interesting lines in aapt&#8217;s documentation:</p>
<p style="text-align: justify"><div id="gist-2116295" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>aapt a[dd] [-v] file.{zip,jar,apk} file1 [file2 ...]</div><div class='line' id='LC2'>&nbsp;&nbsp;Add specified files to Zip-compatible archive.</div><div class='line' id='LC3'>&nbsp;&nbsp;[...]</div><div class='line' id='LC4'>&nbsp;&nbsp;-k  junk path of file(s) added</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2116295/0f5d090d6a39923a13a9b34d2cd8c71ee6195c9c/aapt%20documentation" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2116295#file_aapt documentation" style="float:right;margin-right:10px;color:#666">aapt documentation</a>
            <a href="https://gist.github.com/2116295">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p style="text-align: justify">As you can see, we did <strong>not</strong> use the <em>-k</em> option. Believe me or not, but the tool provided by Android <a title="Thread on StackOverFlow" href="http://stackoverflow.com/a/6572631" target="_blank">is bugged too</a>! Never mind&#8230; after all, an apk file is nothing more than a zip file, so why not use the usual zip tool? I&#8217;ll spare you the details, but applying the same method using zip and checking the files order using the following small python script, we realized that <strong>the suggested workaround simply did not work</strong>.</p>
<p style="text-align: justify"><div id="gist-2107541" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">from</span> <span class="nn">zipfile</span> <span class="kn">import</span> <span class="n">ZipFile</span><span class="p">,</span><span class="n">ZIP_DEFLATED</span><span class="p">,</span><span class="n">ZIP_STORED</span></div><div class='line' id='LC2'><span class="kn">from</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="n">argv</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'><span class="k">with</span> <span class="n">ZipFile</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span><span class="s">&quot;r&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">x</span><span class="p">:</span></div><div class='line' id='LC5'>&nbsp;&nbsp;<span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">x</span><span class="o">.</span><span class="n">infolist</span><span class="p">():</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="n">y</span><span class="o">.</span><span class="n">compress_type</span> <span class="o">==</span> <span class="n">ZIP_DEFLATED</span><span class="p">:</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">print</span> <span class="n">y</span><span class="o">.</span><span class="n">filename</span> <span class="o">+</span> <span class="s">&quot; deflated&quot;</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">elif</span> <span class="n">y</span><span class="o">.</span><span class="n">compress_type</span> <span class="o">==</span> <span class="n">ZIP_STORED</span><span class="p">:</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">print</span> <span class="n">y</span><span class="o">.</span><span class="n">filename</span> <span class="o">+</span> <span class="s">&quot; stored&quot;</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">else</span><span class="p">:</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">print</span> <span class="n">y</span><span class="o">.</span><span class="n">filename</span> <span class="o">+</span> <span class="s">&quot; WTF&quot;</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2107541/32e15131b2ff7e68c1a454604fbf377b1c3284ec/listzip.py" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2107541#file_listzip.py" style="float:right;margin-right:10px;color:#666">listzip.py</a>
            <a href="https://gist.github.com/2107541">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<h2 style="text-align: justify">Working around the workaround</h2>
<p style="text-align: justify"><div class="uds-divider"><a href="#">Top</a></div></p>
<p style="text-align: justify">At this point, we had spent hours trying to work around a bug in Android, using a bugged Android tool, with a method that did not work. But all hope was not lost. After <del>hiding under my desk to cry for a good 10 minutes</del> a good coffee, we decided to try a more brutal method &#8211; and i don&#8217;t mean smashing the phone with a sledgehammer, however tempting it seemed at the moment.</p>
<p style="text-align: justify">So, as the problem comes from the fact that this <em>System.loadLibrary</em> function cannot be trusted to choose between the ARMv7 and non-ARMv7 libraries, we&#8217;ll simply do it ourselves. The problem divided in two main parts:</p>
<p style="text-align: justify">- <em>System.loadLibrary</em> can&#8217;t be trusted to choose between two libraries with the same name, even if they are placed in explicitly named directories. By renaming them to <em>/lib/armeabi/libfoo-core.so</em> and <em>/lib/armeabi-v7a/libfoo-core-v7a.so</em>, we would simply call <em>System.loadLibrary(&#8220;foo-core-v7a&#8221;)</em> if we were on an ARMv7 architecture, and <em>System.loadLibrary(&#8220;foo-core&#8221;)</em> otherwise.</p>
<p style="text-align: justify">- There is no direct way in Java to know if the device you&#8217;re using is ARMv7 or not: we had to create another native library that would be in charge of this choice, cross compiled for ARMv7 and non-ARMv7 architectures, and simply named <em>libfoo.so</em>. A good piece of code being worth a thousand words, here is an example of source code for this <em>libfoo.so</em>:</p>
<p style="text-align: justify"><div id="gist-2119934" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="cp">#include &lt;jni.h&gt;</span></div><div class='line' id='LC2'><span class="cp">#include &lt;cpu-features.h&gt;</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'><span class="n">jboolean</span></div><div class='line' id='LC5'><span class="nf">Java_com_my_namespace_MyClass_isARMv7</span></div><div class='line' id='LC6'><span class="p">(</span><span class="n">JNIEnv</span> <span class="o">*</span><span class="n">env</span><span class="p">,</span> <span class="n">jclass</span> <span class="n">class</span><span class="p">)</span> <span class="p">{</span></div><div class='line' id='LC7'>&nbsp;&nbsp;<span class="kt">uint64_t</span> <span class="n">features</span> <span class="o">=</span> <span class="n">android_getCpuFeatures</span><span class="p">();</span></div><div class='line' id='LC8'>&nbsp;&nbsp;<span class="k">if</span> <span class="p">((</span><span class="n">android_getCpuFamily</span><span class="p">()</span> <span class="o">!=</span> <span class="n">ANDROID_CPU_FAMILY_ARM</span><span class="p">)</span> <span class="o">||</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">((</span><span class="n">features</span> <span class="o">&amp;</span> <span class="n">ANDROID_CPU_ARM_FEATURE_ARMv7</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="o">||</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">((</span><span class="n">features</span> <span class="o">&amp;</span> <span class="n">ANDROID_CPU_ARM_FEATURE_NEON</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">))</span> <span class="p">{</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">JNI_FALSE</span><span class="p">;</span></div><div class='line' id='LC12'>&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC13'>&nbsp;&nbsp;<span class="k">else</span> <span class="p">{</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">JNI_TRUE</span><span class="p">;</span></div><div class='line' id='LC15'>&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC16'><span class="p">}</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2119934/42e62f33d518ac0aa91be36b54ab898a14b620cd/cpucheck.c" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2119934#file_cpucheck.c" style="float:right;margin-right:10px;color:#666">cpucheck.c</a>
            <a href="https://gist.github.com/2119934">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p style="text-align: justify">And the corresponding Java class simply becomes:</p>
<p style="text-align: justify"><div id="gist-2119909" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">my</span><span class="o">.</span><span class="na">namespace</span><span class="o">;</span></div><div class='line' id='LC2'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyClass</span> <span class="o">{</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'>&nbsp;&nbsp;<span class="kd">static</span> <span class="o">{</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">loadLibrary</span><span class="o">(</span><span class="s">&quot;foo&quot;</span><span class="o">);</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="o">(</span><span class="n">isARMv7</span><span class="o">())</span> <span class="o">{</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">loadLibrary</span><span class="o">(</span><span class="s">&quot;foo-core-v7a&quot;</span><span class="o">);</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">else</span> <span class="o">{</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">loadLibrary</span><span class="o">(</span><span class="s">&quot;foo-core&quot;</span><span class="o">);</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC12'>&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC13'><br/></div><div class='line' id='LC14'>&nbsp;&nbsp;<span class="kd">public</span> <span class="kd">native</span> <span class="kt">boolean</span> <span class="nf">isARMv7</span><span class="o">();</span></div><div class='line' id='LC15'>&nbsp;&nbsp;<span class="kd">public</span> <span class="kd">native</span> <span class="kt">int</span> <span class="nf">MyNativeFunction</span><span class="o">();</span></div><div class='line' id='LC16'><span class="o">}</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2119909/7734c4446c7b6429d046c63b15d233e3670ba9dc/MyClass.java" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2119909#file_my_class.java" style="float:right;margin-right:10px;color:#666">MyClass.java</a>
            <a href="https://gist.github.com/2119909">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p style="text-align: justify">This way, the first loaded library makes a native <em>isARMv7()</em> function available, and this function is used to decide which core library must be loaded immediately after.</p>
<p style="text-align: justify">In the end, this workaround happens to be far more reliable and viable in the long term. Even though Google promises that the bug will be fixed in the next release of ICS, experience shows that many users don&#8217;t update their device, or update them months after the release, which will lead to thousands and thousands of &#8220;corrupted&#8221; devices that, despite this bug, we want to support. This trick has the advantage of being far more practical and sure than tinkling with our apk files hoping that it magically fixes a bug, and we&#8217;ll be able to keep it in place for a long time without concern.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moodstocks.com/2012/03/20/ice-cream-sandwich-why-native-code-support-sucks/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Markerless tracking with Moodstocks and Qualcomm SDKs</title>
		<link>http://www.moodstocks.com/2012/03/01/markerless-tracking-with-moodstocks-and-qualcomm-sdks/</link>
		<comments>http://www.moodstocks.com/2012/03/01/markerless-tracking-with-moodstocks-and-qualcomm-sdks/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 09:29:36 +0000</pubDate>
		<dc:creator>Maxime Brenon</dc:creator>
				<category><![CDATA[Developers]]></category>
		<category><![CDATA[Moodstocks SDK]]></category>

		<guid isPermaLink="false">http://www.moodstocks.com/?p=3783</guid>
		<description><![CDATA[In late 2011 Qualcomm, one the world leaders in ARM processors, released a series of tools dedicated to computer vision and augmented reality, optimized for ARM architectures. Two of them immediately caught our attention: FastCV, a low-level computer vision SDK that is not without recalling us of the famous OpenCV, and Vuforia, a high-level, out-of-the-box augmented [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">In late 2011 <strong>Qualcomm</strong>, one the world leaders in ARM processors, released a series of tools dedicated to computer vision and augmented reality, optimized for ARM architectures. Two of them immediately caught our attention: <a title="FastCV" href="https://developer.qualcomm.com/develop/mobile-technologies/computer-vision-fastcv" target="_blank">FastCV</a>, a low-level computer vision SDK that is not without recalling us of the famous <a title="OpenCV" href="http://opencv.willowgarage.com/wiki/" target="_blank">OpenCV</a>, and <a title="Vuforia" href="https://developer.qualcomm.com/develop/mobile-technologies/augmented-reality" target="_blank">Vuforia</a>, a high-level, out-of-the-box augmented reality SDK. We installed their <a title="Qualcomm AR on Android Market" href="https://market.android.com/details?id=org.monosock.shadowdemo">demo application</a>, and were quite impressed by the quality of their <strong>visual tracking</strong>. So, a few weeks ago, we decided to try making something out of these SDKs and started working on a mash-up with <a title="Moodstocks SDK on Github" href="https://github.com/Moodstocks/moodstocks-sdk" target="_blank">our own SDK</a>, that would combine the advantages of both solutions. Moodstocks SDK would provide a robust and real-time image recognition (thanks to its smart sync feature), and we would use one of Qualcomm&#8217;s SDKs to add visual tracking of the detected object.</p>
<p style="text-align: center"><a href="http://www.moodstocks.com/wp-content/uploads/2012/02/vuforia-example.jpg"><img class="alignnone size-full wp-image-3800" src="http://www.moodstocks.com/wp-content/uploads/2012/02/vuforia-example.jpg" alt="" width="600" height="360" /></a></p>
<p style="text-align: justify">Here is how it would work:</p>
<p style="text-align: justify">- Moodstocks SDK processes the camera flow in real-time, and at some point matches the current frame with an object that belongs to its database. It passes this information to one of Qualcomm&#8217;s SDKs. This step has <strong>all the advantages of Moodstocks SDK</strong>, as it uses our synchronization service: it makes applications lighter to download than any application using a bundled database, and allows changes in the database without requiring an application update each time a change, however minor it may be, occurs in the database.</p>
<p style="text-align: justify">- Given that the image has been properly recognized, Qualcomm&#8217;s SDK locates this object on the current frame and starts tracking it on the following frames, with the <strong>impressive fluidity</strong> that we could observe in the demo application, to add to the user experience.</p>
<p style="text-align: center"><a href="http://www.moodstocks.com/wp-content/uploads/2012/02/vuforia.png"><img class="alignnone size-full wp-image-3801" src="http://www.moodstocks.com/wp-content/uploads/2012/02/vuforia.png" alt="" width="293" height="135" /></a></p>
<p style="text-align: justify">We decided to begin with Vuforia SDK, as it seemed easier of use. Its strength for most developers is that it&#8217;s quite easy to use: you add Vuforia SDK to your application, upload all the images you want to recognize and track (via a convenient web interface), and in return you download one single <em>qcar-resource.dat</em> file containing the data necessary to perform these operations on your application. However, <strong>this full packaging was the source of several problems</strong> in our case:</p>
<p style="text-align: justify">- the first is that you cannot separate the image recognition among a database from the location and tracking part. A possible trick to separate these two functions would have been to create several of these <em>.dat</em> files, one for each image we wanted to track: as image recognition among a database of only one image is a trivial task, Vuforia SDK would matter of factly do no more that tracking. This could have worked, if Vuforia had not supported a single <em>.dat</em> file that must be named <em>qcar-resource.dat</em>&#8230; and juggling with some on the fly file renaming would not have been a really practical solution.</p>
<p style="text-align: justify">- the second one is that these <em>.dat</em> files are quite heavy, and we wanted to keep the advantages of our synchronization. Using one (or several) of these files would require to manage a second, heavier database than the one used for our image recognition.</p>
<p style="text-align: center"><a href="http://www.moodstocks.com/wp-content/uploads/2012/02/vuforia-sdk.png"><img class="alignnone  wp-image-3804" src="http://www.moodstocks.com/wp-content/uploads/2012/02/vuforia-sdk.png" alt="" width="576" height="432" /></a></p>
<p style="text-align: justify">In the end, Vuforia appeared to be too high-level and not flexible enough for our needs&#8230; all these tricks were far too dirty for us to implement them, so we decided to try our chance with the <strong>lower-level FastCV SDK</strong>.</p>
<p style="text-align: justify">We began by searching inspiration in the sample codes and documentation of the SDK. That was quickly done: the two sample codes illustrate hardly a tenth of the functions available in the library, and the documentation of each functions holds in two lines tops. But well, ok, this SDK is still quite young and needs to mature for some time. We went on anyway. After a bit of fumbling through the documentation, FastCV SDK seemed to contain everything we needed to implement the tracking part in itself without too much pain: a <a title="FastCV tracking function" href="https://developer.qualcomm.com/docs/fastcv/api/group__object__detection.html#ga0af1c588201a116f0ac302da8cfc102f">ready-to-use tracking function</a>, and an <a title="FastCV feature detection function" href="https://developer.qualcomm.com/docs/fastcv/api/group__feature__detection.html#ga1aa689c12ad05c1572077dee048cd2e3">efficient features detector</a> to feed it. Of course, it would require a bit of wrapping to work, but it had the advantage of doing what we needed it to do, nothing more, nothing less. So we had what we needed to track features&#8230; Cool. But we couldn&#8217;t just track <em>any</em> features on the frame: we first had to locate the object recognized by Moodstocks SDK and extract features to track <em>only</em> from this object. And that&#8217;s when things got messy.</p>
<p style="text-align: center"><a href="http://www.moodstocks.com/wp-content/uploads/2012/02/Capture-d’écran-2012-02-29-à-18.04.211.png"><img class="alignnone size-full wp-image-3811" src="http://www.moodstocks.com/wp-content/uploads/2012/02/Capture-d’écran-2012-02-29-à-18.04.211.png" alt="" width="434" height="69" /></a></p>
<p style="text-align: justify">We tested several different tactics using the different tools included in FastCV. Our first idea implied using a quite classical method in image matching: pre-process the image to track to extract interesting features, describe them, and search for these features in the camera frames at runtime. As the task of finding a reference image in a camera frame when we do know it&#8217;s there (from our own SDK) is quite simple, we hoped to do this using only a few features, which would have had the advantage of allowing to package the lightweight necessary information (aka the descriptors) <a title="Encoding metadata in image IDs" href="https://github.com/Moodstocks/moodstocks-api/wiki/api-v2-help-objects#wiki-metadata" target="_blank">in a smart way</a> by encoding this information directly within each image identifier. That&#8217;s for the theory&#8230; but in practice, it appeared that FastCV proposed only <a title="FastCV descriptor" href="https://developer.qualcomm.com/docs/fastcv/api/group__object__detection.html#gab82f782805a808e65340c1e069fb029a" target="_blank">one, never-heard-of descriptor</a>. From its concise documentation, it seemed to be some kind of custom, lightweight <a title="SURF descriptors" href="http://www.vision.ee.ethz.ch/~surf/" target="_blank">SURF</a>-like descriptor. We tested it, and realized that it would never be robust and discriminant enough to allow image detection with the small number of reference features we could afford&#8230; and we found ourselves once more back to the beginning of our research. We tried a few other methods, before realizing that as we went on, our ideas were becoming more and more heavy and impractical&#8230; we just couldn&#8217;t find a simple and smart enough way to go through this tracking initialization step using FastCV, and creating a 1000-line-long, barely understandable piece of code would not have served the purpose of illustrating what could be done using both FastCV and our SDK.</p>
<p style="text-align: justify">So after a few days of work, we simply decided to give up -at least for now- on this project. <strong>Let it not be said that we criticize Qualcomm&#8217;s SDKs</strong>: I would personally encourage developers to use them. Only, none of them was fitted to the specific use we wanted. Vuforia is a perfect SDK for any developer who wants to implement painless augmented reality and doesn&#8217;t specifically care about the size or flexibility of their apps. It won&#8217;t fail to amaze their users and make their eyes shine. Considering FastCV, I would encourage anyone who work in mobile computer vision to use it as an optimized, efficient toolbox from which to pick elementary functions that will boost your applications. As for us, we&#8217;ll keep an eye on the evolution of these two young SDKs and won&#8217;t miss the opportunity to resume this project if the opportunity arises.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moodstocks.com/2012/03/01/markerless-tracking-with-moodstocks-and-qualcomm-sdks/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>JPEC: the why&#8217;s and the how&#8217;s.</title>
		<link>http://www.moodstocks.com/2012/02/10/jpec-the-whys-and-the-hows/</link>
		<comments>http://www.moodstocks.com/2012/02/10/jpec-the-whys-and-the-hows/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 14:02:07 +0000</pubDate>
		<dc:creator>Maxime Brenon</dc:creator>
				<category><![CDATA[Developers]]></category>

		<guid isPermaLink="false">http://www.moodstocks.com/?p=3688</guid>
		<description><![CDATA[A few weeks ago, we released a lightweight, minimalistic JPEG encoder in C (JPEC), that we use in our SDK to compress frames. There are already so many libraries dedicated to JPEG encoding/decoding that even finding an available name for it was not an easy task&#8230; so why bother to implement a new one? The answer holds [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">A few weeks ago, we released a <strong>lightweight, minimalistic JPEG encoder in C</strong> (<a title="JPEC on Github" href="https://github.com/Moodstocks/jpec" target="_blank">JPEC</a>), that we use in our <a title="Moodstocks-SDK on Github" href="https://github.com/Moodstocks/moodstocks-sdk" target="_blank">SDK</a> to compress frames. There are already so many libraries dedicated to JPEG encoding/decoding that even finding an available name for it was not an easy task&#8230; so why bother to implement a new one?</p>
<p style="text-align: justify;">The answer holds in one word: <strong>simplicity</strong>. We just didn&#8217;t need  90% of the possibilities offered by most of these libraries. No decoding, no color, no such &#8216;expert&#8217; options as progressive encoding or variable block sizes: we wanted to be able to compress grayscale images, no more, no less. Sure, we could have used one of them anyway, as they all perfectly do their job&#8230; but we just didn&#8217;t want to burden our SDK with these unused functions. The other option was to use platform-specific dynamic libraries such as Apple&#8217;s Image I/O framework, but they are, well&#8230; platform-specific. So, we decided to implement our own, customized, vertical encoder. And yes,<strong> it was worth the effort:</strong></p>
<p>- the result holds in about 600 LOC,<br />
- compiled for ARMv7 architecture using LLVM-GCC, it weights no more than 12kB,<br />
- it compresses a 360&#215;480 image on an iPhone 4 in 35ms, versus 22ms for Apple&#8217;s Image I/O framework&#8230; and can probably still be optimized using NEON instruction set.</p>
<p style="text-align: justify;">But let&#8217;s go back in time a little, and give a little hindsight on the <strong>sneaky little traps</strong> that made all the fun of this task.</p>
<p style="text-align: justify;">The JPEG compression could in fact be split into two main steps: a more &#8216;mathematical&#8217; part that compresses an image into a series of numbers, and an &#8216;encoding&#8217; part where we store these numbers as efficiently as possible in a file. The mathematical part was far from being the hardest to implement: basically, following <a title="JPEG Encoding" href="http://en.wikipedia.org/wiki/JPEG#Encoding">Wikipedia</a> was nearly enough to implement it, and even provided some quite efficient tricks such as the use of <a title="In french, sorry!" href="http://fr.wikipedia.org/wiki/Transformée_en_cosinus_discrète#Exemple_pour_N_.3D_8" target="_blank">Chen&#8217;s algorithm</a> to compute a Discrete Cosine Transform with a reduced number of operations. The difficulty laid in the encoding part.</p>
<p style="text-align: center;"><a href="http://www.moodstocks.com/wp-content/uploads/2012/02/jpec_maths.png"><img class="alignnone size-full wp-image-1119" src="http://www.moodstocks.com/wp-content/uploads/2012/02/jpec_maths.png" alt="" width="437" height="177" /></a></p>
<p style="text-align: justify;">Strangely, that&#8217;s when <a title="Entropy encoding" href="http://en.wikipedia.org/wiki/JPEG#Entropy_coding">Wikipedia</a> (as well as a good part of the other resources on JPEG available on the web) becomes far more blurry on how to proceed. What makes this step tricky is that, to minimize the size of JPEG files, data is stored using Huffman encoding bit after bit, regardless of the usual byte structure. It looks like a good idea (and it is, in the end, a very powerful idea), but it makes debugging your output JPEG files absolutely awful. Some part of the data may take 3 bits and the next one 17, etc&#8230; which makes absolutely impossible to track the origin of your bugs.</p>
<p style="text-align: center;"><a href="http://www.moodstocks.com/wp-content/uploads/2012/02/Capture-d’écran-2012-02-10-à-12.17.57.png"><img class="alignnone size-full wp-image-1119" src="http://www.moodstocks.com/wp-content/uploads/2012/02/Capture-d’écran-2012-02-10-à-12.17.57.png" alt="" width="219" height="72" /></a></p>
<p style="text-align: justify;">And then, after a few hours (not among the most pleasant of my life) of bit by bit debugging using an hexadecimal editor, I discovered <a title="JPEGsnoop" href="http://www.impulseadventure.com/photo/jpeg-snoop.html" target="_blank">JPEGsnoop</a>. This small software, whose highest flaw is probably to be available only for Windows, simply did in a handful of seconds what had caused my headaches for hours. It analyzes the structure of your JPEG file, and gives you some great hints on where and why it ended up corrupted. It simply saved my day, and in a matter of hours we had a functional library.</p>
<p style="text-align: center;"><a href="http://www.moodstocks.com/wp-content/uploads/2012/02/Capture-d’écran-2012-02-10-à-12.26.21-e1328873377943.png"><img class="alignnone size-full wp-image-1119" src="http://www.moodstocks.com/wp-content/uploads/2012/02/Capture-d’écran-2012-02-10-à-12.26.21-e1328873377943.png" alt="" width="500" height="229" /></a></p>
<p style="text-align: justify;">From &#8216;functional&#8217; to &#8216;releasable&#8217;, there remained a last difficulty: clearly separate the different steps to make all of this understandable&#8230; and maintainable. Once the maths, the encoding and the actual bit by bit file writing were not a great soup of mixed functions anymore, we had our minimalistic encoder. And now <a title="JPEC on Github" href="https://github.com/Moodstocks/jpec" target="_blank">you can have it too</a>, you lucky ones!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moodstocks.com/2012/02/10/jpec-the-whys-and-the-hows/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Street art can now be curated thanks to image recognition</title>
		<link>http://www.moodstocks.com/2011/11/14/street-art-can-now-be-curated-thanks-to-image-recognition/</link>
		<comments>http://www.moodstocks.com/2011/11/14/street-art-can-now-be-curated-thanks-to-image-recognition/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 15:15:11 +0000</pubDate>
		<dc:creator>Clément Delangue</dc:creator>
				<category><![CDATA[Developers]]></category>
		<category><![CDATA[Marketers]]></category>
		<category><![CDATA[Moodstocks API]]></category>
		<category><![CDATA[Start-uppers]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[art]]></category>
		<category><![CDATA[curation]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[mashup]]></category>
		<category><![CDATA[qrators]]></category>
		<category><![CDATA[qrtrs]]></category>
		<category><![CDATA[recognition]]></category>
		<category><![CDATA[street]]></category>
		<category><![CDATA[street-art]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://www.moodstocks.com/?p=3525</guid>
		<description><![CDATA[Have you ever wanted to know more about this fabulous artwork you&#8217;ve just seen in the street? Or to tell the world about the super cool artist who mastered that other one? It&#8217;s now possible thanks to Qrators. It leverages our image recognition platform to aggregate Tweets about artworks. Awesome! The cool thing is that you [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever wanted to know more about this fabulous artwork you&#8217;ve just seen in the street? Or to tell the world about the super cool artist who mastered that other one? It&#8217;s now possible thanks to <a href="http://www.qrators.com/">Qrators</a>. It leverages our <a href="http://moodstocks.com/gallery">image recognition platform</a> to aggregate Tweets about artworks. Awesome!</p>
<p><object width="500" height="281"><param name="movie" value="http://www.youtube.com/v/pTZuWTDi470?version=3&#038;feature=oembed"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/pTZuWTDi470?version=3&#038;feature=oembed" type="application/x-shockwave-flash" width="500" height="281" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>The cool thing is that you don&#8217;t even need to download an app to use it. The developer behind the project has made the most of our tutorial about how to develop a <a href="https://github.com/Moodstocks/moodstocks-api/wiki/ms-twitter-mashup">Moodstocks &#8211; Twitter mashup</a> to be up and running in a breeze. So just tweet the picture of an artwork mentioning <a href="https://twitter.com/#!/Qrtrs">@qrtrs</a> to join the fun. It&#8217;s that easy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moodstocks.com/2011/11/14/street-art-can-now-be-curated-thanks-to-image-recognition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OSDC.fr 2011: Lua, Python, Redis and friends</title>
		<link>http://www.moodstocks.com/2011/09/26/osdc-fr-2011-lua-python-redis-and-friends/</link>
		<comments>http://www.moodstocks.com/2011/09/26/osdc-fr-2011-lua-python-redis-and-friends/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 20:52:26 +0000</pubDate>
		<dc:creator>cedric</dc:creator>
				<category><![CDATA[Developers]]></category>

		<guid isPermaLink="false">http://www.moodstocks.com/?p=3488</guid>
		<description><![CDATA[Last week-end, we were very pleased to attend OSDC.fr, this year again, at Eurosites George V, Paris. OSDC is definitely a great opportunity to meet passionate developers with different culture and expertise. And also yet another reason to drink a beer! Some really good talks were given this year. To name a few, I really appreciated: - the Red programming [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.moodstocks.com/wp-content/uploads/2011/09/osdcfr2011.png"><img class="alignleft size-full wp-image-3490" title="osdcfr2011" src="http://www.moodstocks.com/wp-content/uploads/2011/09/osdcfr2011.png" alt="" width="258" height="78" /></a>Last week-end, we were very pleased to attend <a href="http://act.osdc.fr/osdc2011fr/">OSDC.fr</a>, this year <a href="http://www.moodstocks.com/2010/10/14/osdc-fr-2010-redis-and-friends-at-la-villette/">again</a>, at Eurosites George V, Paris. OSDC is definitely a great opportunity to meet passionate developers with different culture and expertise. And also yet another reason <a href="http://twitter.com/#!/amicel/status/117652671506288640">to drink a beer</a>!</p>
<p>Some really good talks were given this year. To name a few, I really appreciated:</p>
<p>- the <a href="http://www.red-lang.org/">Red programming language</a> talk by <a href="http://twitter.com/#!/red_lang">Nenad Rakocevic</a>,<br />
- the Ruby / C bindings via <a href="https://github.com/ffi/ffi">FFI</a> presentation by <a href="http://blog.marc-andre.ca/">Marc-André Lafortune</a> &#8211; that&#8217;s a really good alternative to the <em>standard</em> way to <a href="http://people.apache.org/~rooneg/talks/ruby-extensions/ruby-extensions.html">extend Ruby with C</a>,<br />
- the very good introduction to the <a href="http://www.haskell.org/haskellwiki/Haskell">Haskell</a> functional programming language <a href="http://uuu.enseirb-matmeca.fr/~robertv/pp/index.php">Valentin Robert</a> gave, featuring interesting concepts such as <a href="http://en.wikipedia.org/wiki/Lazy_evaluation">lazy evaluation</a> or pure functions.</p>
<p>But for sure the <a href="http://www.lua.org/">Lua language</a> definitely made the buzz with no more than 3 talks &#8211; a talk covering the basics, another one focused on the really impressive <a href="http://luajit.org/">LuaJIT</a> project (aka <a href="http://en.wikipedia.org/wiki/Just-in-time_compilation">Just-In-Time compiler</a> for Lua), both by <a href="http://sites.google.com/site/fperrad/home">François Perrad</a>, and a last one covering its native integration within <a href="http://redis.io/">Redis</a> (aka <a href="http://antirez.com/post/scripting-branch-released.html">scripting-branch</a>) by <a href="http://twitter.com/#!/pchapuis">Pierre Chapuis</a>.</p>
<p>Nothing to say that the ability to extend Redis with Lua scripting is a killer feature! For those who are familiar with <a href="http://fallabs.com/">Tokyo products</a> it is in some ways pretty similar to what has been done within <a href="http://www.igvita.com/2009/07/13/extending-tokyo-cabinet-db-with-lua/">Tokyo Tyrant</a>.</p>
<p>So let met say congrats to all <a href="http://act.osdc.fr/osdc2011fr/talks">speakers</a> and participants, thanks to the organization team and see you next year!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moodstocks.com/2011/09/26/osdc-fr-2011-lua-python-redis-and-friends/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Volkswagen launches a urban game based on scanning</title>
		<link>http://www.moodstocks.com/2011/09/16/volkswagen-launches-an-urban-game-based-on-scanning/</link>
		<comments>http://www.moodstocks.com/2011/09/16/volkswagen-launches-an-urban-game-based-on-scanning/#comments</comments>
		<pubDate>Fri, 16 Sep 2011 14:16:48 +0000</pubDate>
		<dc:creator>Clément Delangue</dc:creator>
				<category><![CDATA[Developers]]></category>
		<category><![CDATA[Marketers]]></category>
		<category><![CDATA[Moodstocks]]></category>
		<category><![CDATA[Moodstocks API]]></category>
		<category><![CDATA[Moodstocks SDK]]></category>
		<category><![CDATA[automotive]]></category>
		<category><![CDATA[car]]></category>
		<category><![CDATA[gaming]]></category>
		<category><![CDATA[Image recognition]]></category>
		<category><![CDATA[Ricard]]></category>
		<category><![CDATA[scavenger hunt]]></category>
		<category><![CDATA[Volkswagen]]></category>

		<guid isPermaLink="false">http://www.moodstocks.com/?p=3430</guid>
		<description><![CDATA[Many of you underlined the potential of our tech for gaming apps. Many already experienced it, both with our real-life scavenger hunt and the Ricard Mix Code app. And Volkswagen understood it well so they launched the Golf Story Game. The rules are simple: you score each time you scan an ad in magazines or on billboards from the [...]]]></description>
			<content:encoded><![CDATA[<p>Many of you underlined the potential of our <a href="http://moodstocks.com">tech</a> for gaming apps. Many already experienced it, both with our <a href="http://www.moodstocks.com/2011/08/04/turn-the-street-into-your-playground-with-object-recognition/">real-life scavenger hunt </a>and the <a href="http://www.moodstocks.com/gallery/">Ricard Mix Code app</a>. And <a href="http://www.vw.com/en.html">Volkswagen</a> understood it well so they launched the <a href="http://golfstory.be/fr/home">Golf Story Game</a>.</p>
<p><img class="alignleft size-full wp-image-3439" src="http://www.moodstocks.com/wp-content/uploads/2011/09/Golf-story-game.gif" alt="" width="279" height="197" />The rules are simple: you score each time you scan an ad in magazines or on billboards from the dedicated iPhone and Android apps.</p>
<p>Along with points and badges, you can win a wide range of stuff, from <a href="http://golfstory.be/fr/home">iPads to a real Golf Cabrio</a>. Pretty cool, right?</p>
<p>So far the apps are only available in Belgium. But feel free to ask <a href="http://twitter.com/VW">Volkswagen </a>to expand it to the rest of the world!</p>
<p>We&#8217;d like to thank our partners for their awesome integration work: <a href="http://www.inthepocket.mobi">In The Pocket</a> (app design and development) and <a href="http://www.ddb.be/">Tribal DDB Brussel</a> (project leader). You guys rock!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moodstocks.com/2011/09/16/volkswagen-launches-an-urban-game-based-on-scanning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When object recognition goes off-line!</title>
		<link>http://www.moodstocks.com/2011/08/31/when-object-recognition-goes-off-line/</link>
		<comments>http://www.moodstocks.com/2011/08/31/when-object-recognition-goes-off-line/#comments</comments>
		<pubDate>Wed, 31 Aug 2011 13:03:25 +0000</pubDate>
		<dc:creator>Clément Delangue</dc:creator>
				<category><![CDATA[Developers]]></category>
		<category><![CDATA[Marketers]]></category>
		<category><![CDATA[Moodstocks API]]></category>
		<category><![CDATA[Start-uppers]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[3G]]></category>
		<category><![CDATA[object recognition]]></category>
		<category><![CDATA[off-line]]></category>
		<category><![CDATA[offline]]></category>
		<category><![CDATA[scanner]]></category>
		<category><![CDATA[wifi]]></category>

		<guid isPermaLink="false">http://www.moodstocks.com/?p=3389</guid>
		<description><![CDATA[Some people told us: &#8220;Great, you guys recognize objects in real-time in Wifi and 3G but what happens in the tube where the network sucks?&#8221;. Well today we are very proud to let you know that it works there too thanks the off-line mode we&#8217;ll be launching very soon: As you can see image recognition has [...]]]></description>
			<content:encoded><![CDATA[<p>Some people told us: &#8220;Great, you guys recognize objects in <a href="http://www.moodstocks.com/2011/08/08/when-object-recognition-becomes-real-time/">real-time</a> in Wifi and 3G but what happens in the tube where the network sucks?&#8221;. Well today we are very proud to let you know that it works there too thanks the off-line mode we&#8217;ll be launching very soon:</p>
<p><object width="500" height="306"><param name="movie" value="http://www.youtube.com/v/tsxe23b12eU?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/tsxe23b12eU?version=3" type="application/x-shockwave-flash" width="500" height="306" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>As you can see <a href="http://www.moodstocks.com">image recognition</a> has never been faster! A lot of people gave it a try last week during an <a href="http://www.meetup.com/S-O-H-A/events/29812131/">apero</a> we organized in our loft and they were thrilled. If you&#8217;re a developer and want a beta access to the brand new scanner, just <a href="http://www.moodstocks.com">let us know</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moodstocks.com/2011/08/31/when-object-recognition-goes-off-line/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Augmented reality on the iPad thanks to image recognition</title>
		<link>http://www.moodstocks.com/2011/08/29/augmented-reality-on-the-ipad-thanks-to-image-recognition/</link>
		<comments>http://www.moodstocks.com/2011/08/29/augmented-reality-on-the-ipad-thanks-to-image-recognition/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 12:42:00 +0000</pubDate>
		<dc:creator>Clément Delangue</dc:creator>
				<category><![CDATA[Developers]]></category>
		<category><![CDATA[Marketers]]></category>
		<category><![CDATA[Moodstocks]]></category>
		<category><![CDATA[Moodstocks API]]></category>
		<category><![CDATA[AR]]></category>
		<category><![CDATA[Augmented]]></category>
		<category><![CDATA[augmentée]]></category>
		<category><![CDATA[Citroën]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[réalité]]></category>
		<category><![CDATA[reality]]></category>
		<category><![CDATA[recognition]]></category>

		<guid isPermaLink="false">http://www.moodstocks.com/?p=3232</guid>
		<description><![CDATA[As you guys know, we are now able to perform real-time object recognition here at Moodstocks. And it opens tons of new opportunities. For example, overlaying information directly on the screen and refreshing it depending on the object you&#8217;re pointing to. That&#8217;s what we did to &#8220;augment&#8221; the Citroën Creative Tour, celebrating the 80th birthday [...]]]></description>
			<content:encoded><![CDATA[<p>As you guys know, we are now able to perform <a href="http://www.moodstocks.com/2011/08/08/when-object-recognition-becomes-real-time/">real-time object recognition</a> here at <a href="http://www.moodstocks.com">Moodstocks</a>. And it opens tons of new opportunities.</p>
<p>For example, overlaying information directly on the screen and refreshing it depending on the object you&#8217;re pointing to. That&#8217;s what we did to &#8220;augment&#8221; the <a href="http://www.creativetour.citroen.com/">Citroën Creative Tour</a>, celebrating the 80th birthday of the <a href="http://www.piecescitroensport.citroen.com/CWW/en-US/HISTORY/ADVENTURE/YellowCruise/">Yellow Cruise</a>.</p>
<p><object width="500" height="306"><param name="movie" value="http://www.youtube.com/v/kB2NWvWIVsk?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/kB2NWvWIVsk?version=3" type="application/x-shockwave-flash" width="500" height="306" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>And thousands of people loved the experience be it in Paris or Berlin (soon in Moscow and Beijing). For the record, it&#8217;s been developed within a couple of days leveraging our image recognition <a href="http://www.moodstocks.com/how-it-works/">API</a>. Can you believe it?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moodstocks.com/2011/08/29/augmented-reality-on-the-ipad-thanks-to-image-recognition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Every object has an INVISIBLE QR Code with object recognition</title>
		<link>http://www.moodstocks.com/2011/08/17/every-object-has-an-invisible-qr-code-with-object-recognition/</link>
		<comments>http://www.moodstocks.com/2011/08/17/every-object-has-an-invisible-qr-code-with-object-recognition/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 17:07:45 +0000</pubDate>
		<dc:creator>Clément Delangue</dc:creator>
				<category><![CDATA[Marketers]]></category>
		<category><![CDATA[Moodstocks]]></category>
		<category><![CDATA[Start-uppers]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Flashcode]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[Invisible]]></category>
		<category><![CDATA[Qooery]]></category>
		<category><![CDATA[QR]]></category>
		<category><![CDATA[recognition]]></category>

		<guid isPermaLink="false">http://www.moodstocks.com/?p=3073</guid>
		<description><![CDATA[A few weeks ago we launched the INVISIBLE QR Code: A lot of you guys wondered how invisible QR codes work. Well, they actually don&#8217;t exist! We rely on our state-of-the-art image recognition tech to recognize the book cover itself. The invisible QR Code stuck to it is nothing but a joke! We&#8217;re very sorry if we [...]]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago we launched the <a href="http://www.moodstocks.com/2011/07/27/meet-the-first-invisible-qr-code/">INVISIBLE QR Code</a>:</p>
<p><object width="500" height="306"><param name="movie" value="http://www.youtube.com/v/8iPgYV-__mo?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/8iPgYV-__mo?version=3" type="application/x-shockwave-flash" width="500" height="306" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>A lot of you guys wondered how invisible QR codes work. Well, they actually don&#8217;t exist! We rely on our state-of-the-art <a href="http://www.moodstocks.com">image recognition tech</a> to recognize the book cover itself. The <a href="../2011/07/27/meet-the-first-invisible-qr-code/">invisible QR Code</a> stuck to it is nothing but a joke!</p>
<p>We&#8217;re very sorry if we fooled you. We wanted to emphasize that <a href="http://www.moodstocks.com">image recognition</a> works right here right now. It&#8217;s now easier than ever to deploy and use it. And thanks to <a href="http://www.moodstocks.com">Moodstocks</a> it&#8217;s in <a href="http://www.moodstocks.com/2011/08/08/when-object-recognition-becomes-real-time/">real-time</a> even on 3G networks:</p>
<p><object width="500" height="306"><param name="movie" value="http://www.youtube.com/v/bkqq_iHVOJE?version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/bkqq_iHVOJE?version=3" type="application/x-shockwave-flash" width="500" height="306" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>Do you also want to <a href="http://www.moodstocks.com/galery">use</a> <a href="http://www.moodstocks.com">image recognition</a> to turn any object into its own QR code? We have <a href="http://www.moodstocks.com/community/">everything</a> you need to get yourself up and running in minutes. And if you have any question: feel free to <a href="http://www.facebook.com/moodstocks">connect</a>. We&#8217;re here to help!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moodstocks.com/2011/08/17/every-object-has-an-invisible-qr-code-with-object-recognition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

