Posts Tagged ‘javascript’

How to bypass WebGL Sop restriction v2

December 5th, 2011

I’ve previously posted a trick to bypass the WebGL same origin policy restriction in a particular context. But my solution had a major drawback: it was slow due to jpeg decoding in javascript. Hopefully I’ve implemented a new solution which is way much faster thanks to John Bauman suggestion and it works like a charm!

var xhr = new XMLHttpRequest();"GET", JPEG_URL, true);
xhr.responseType = "arraybuffer";
xhr.onload = function() {
	var img = new Image();
	img.onload = function() {
		var tex = new THREE.Texture(this);
		//do something with this texture...
	img.src = arrayBufferDataUri(xhr.response);

The function “arrayBufferDataUri” at the line 10 allow to speed-up the conversion from ArrayBuffer to base64 ascii string by avoiding an extra copy needed to use window.btoa. I’ve found this function here:

function arrayBufferDataUri(raw) {
	var base64 = '';
	var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
	var bytes = new Uint8Array(raw);
	var byteLength = bytes.byteLength;
	var byteRemainder = byteLength % 3;
	var mainLength = byteLength - byteRemainder;
	var a, b, c, d;
	var chunk;
	// Main loop deals with bytes in chunks of 3
	for (var i = 0; i < mainLength; i = i + 3) {
		// Combine the three bytes into a single integer
		chunk = (bytes[i] << 16) | (bytes[i + 1] << 8 ) | bytes[i + 2];
		// Use bitmasks to extract 6-bit segments from the triplet
		a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18
		b = (chunk & 258048) >> 12;   // 258048   = (2^6 - 1) << 12
		c = (chunk & 4032) >> 6;      // 4032     = (2^6 - 1) << 6
		d = chunk & 63;               // 63       = 2^6 - 1
		// Convert the raw binary segments to the appropriate ASCII encoding
		base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]
	// Deal with the remaining bytes and padding
	if (byteRemainder == 1) {
		chunk = bytes[mainLength];
		a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2
		// Set the 4 least significant bits to zero
		b = (chunk & 3) << 4;   // 3   = 2^2 - 1
		base64 += encodings[a] + encodings[b] + '==';
	else if (byteRemainder == 2) {
		chunk = (bytes[mainLength] << 8 ) | bytes[mainLength + 1];
		a = (chunk & 16128) >> 8; // 16128 = (2^6 - 1) << 8
		b = (chunk & 1008) >> 4;  // 1008  = (2^6 - 1) << 4
		// Set the 2 least significant bits to zero
		c = (chunk & 15) << 2;    // 15    = 2^4 - 1
		base64 += encodings[a] + encodings[b] + encodings[c] + '=';
	return "data:image/jpeg;base64," + base64;

I’ve only used this code for my Google Chrome PhotoSynth WebGL extension. This is why I don’t have added extra check for other browser (line 10: xhr.mozResponseArrayBuffer || xhr.response).


Three.js PhotoSynth Viewer with pictures and new UI

October 3rd, 2011

I really like JS development and my Google Chrome PhotoSynth extension is a really good opportunity to experiment new thing with WebGL. So I’ve added new features to my previous version:

  • Navigation system (like the Microsoft Silverlight one)
  • Thumbnails display in the WebGL content [beta]

Adding the pictures wasn’t easy: it is not possible to draw a texture coming from another domain on a WebGL context for security reason. I have found a workaround for this issue (AFAIK unknown: see my post about it). I’ve also managed to “clone” the UI of the Silverlight viewer and to find out how to parse some navigation information from the JSON file provided with each Synth. But I wish that the PhotoSynth team gives me some information about the meaning of some other undocumented parameters…

I won’t release this new version as it is CPU hungry (because of the WebGL restriction workaround), but if the PhotoSynth team adds the missing CORS header this could solve the current WebGL restriction in a cleaner way ;-) .

A new feature is coming too (related to my new work at Acute3D).


How to bypass WebGL Sop restriction

October 3rd, 2011

Google Chrome and Firefox are blocking cross-domain image in WebGL (because of a security issue). This is really annoying when you want to display image from other domain in WebGL. To bypass this same-origin-policy restriction you have several options:

Ok, to be honest my “trick” only work for browser extensions (tested with Google Chrome extension only). How is it working?

  • Add the domain in the list of allowed cross-domain ajax call in the manifest of the extension.
  • Do a binary ajax request on the jpeg
  • Parse the jpeg in javascript using jpgjs
  • Fill the WebGL texture with the jpeg decoded in JS

The drawbacks are that it can only be used by browser extensions and that JS jpeg decoding is slow compared to native decoding.

I’ve used this workaround to add the pictures in my WebGL PhotoSynth Viewer extension.

I’ve posted a new version which is really much faster.


My 5 years old Quiksee competitor

September 27th, 2010

I’ve just heard that Google has bought Quiksee for 10 millions $. I was curious about Quiksee virtual tour technology as I’ve written myself something that seem equivalent 5 years ago. But their website doesn’t explain anything, neither their “nice” demo clip.

Like Quiksee, my virtual tour system is composed of panoramic pictures linked by videos. The first version of my virtual tour was created in 2005 (2 years before Google Street View launch).

During my internship in the beautiful city of the Puy-en-velay I’ve taken around 1800 pictures to create a virtual tour. This virtual tour is composed of 18 panoramic pictures and 44 videos links. I’ve first created a full featured version using Flash for video playback (Yajev) and then I’ve improved this version with a full HTML5 version (Html5 Virtual Tour).


Ok, I’m not gifted to find a product name (Yajev -> Yaj3v (l33t) -> yajvvv -> yet another virtual visit viewer). My first demo of Yajev was created in 2005 and was showing a small French village (5000 pictures, 51 videos and 20 panoramic pictures), but it’s not visible anymore.

->Live demo<-

Best viewed with IE9 (there is a bug with the Flash player with the other browser)


  • 360° panoramic player
  • Flash video player
  • Map
  • Hotspot links and tips displayed over panoramic picture
  • Dijkstra shortest path finder and player
  • Plugin system: compass, debug, 3d sound, lytebox, debug
  • XML based virtual tour configuration

Html5 VirtualTour

This version is 2 years old now. Unfortunately the videos were encoded with Theora, so this demo can’t run on IE9. So this demo is best viewed with Google Chrome and Firefox.

->Live demo<-

Best viewed with Google Chrome


  • 360° panoramic player with smooth animation
  • Html5 video player
  • Canvas map
  • Hotspot links and tips displayed over panoramic picture
  • XML based virtual tour configuration


There is no support for this virtual tour ! The javascript files are not obfuscated: you are free to do what you want with it. I’ve created this to improve my javascript skills, but I’m much more interested by computer vision now, so I’m sorry but I can’t provide any support for Yajev nor Html5 Virtual Tour.