Index: other-projects/nz-flag-design/trunk/similarity-2d/display-flags.jsp
===================================================================
--- other-projects/nz-flag-design/trunk/similarity-2d/display-flags.jsp	(revision 29625)
+++ other-projects/nz-flag-design/trunk/similarity-2d/display-flags.jsp	(revision 29626)
@@ -10,4 +10,5 @@
     <script src="../js/jquery-ui-1.11.2.smoothness/jquery-ui.js"></script>
 
+    <script src="js-lib/Colour.js"></script>
     <script src="flag-processing.js"></script>
 
Index: other-projects/nz-flag-design/trunk/similarity-2d/flag-processing.js
===================================================================
--- other-projects/nz-flag-design/trunk/similarity-2d/flag-processing.js	(revision 29625)
+++ other-projects/nz-flag-design/trunk/similarity-2d/flag-processing.js	(revision 29626)
@@ -2,4 +2,7 @@
 var progressVal = 0;
 
+var show_progress = 5;
+
+var timeout_delay = 100;
 
 function drawImage(imageObj, canvasId) {
@@ -10,16 +13,106 @@
         imageWidth = imageObj.width,
         imageHeight = imageObj.height;
+
     context = imgCanvas.getContext('2d');
     context.drawImage(imageObj, imageX, imageY, imageWidth, imageHeight);
     imageData = context.getImageData(imageX, imageY, imageWidth, imageHeight);
-    //data = imageData.data;
+
     return imageData;
 }
 
+function createHSLHistogram(imageObj, quant)
+{
+    var i;
+
+    if (!$('#hsl_canvas').length) {
+	$('<canvas>', {id: 'hsl_canvas'}).hide().appendTo('body');
+    }
+
+    imageData = drawImage(imageObj,'hsl_canvas');
+
+    var outputLength = quant * quant * quant;
+    var outputArray = new Array(outputLength);
+    for (i=0; i<outputLength; i++) {
+	outputArray[i] = 0;
+    }
+
+    var total = 0.0;
+            
+    var log2 = Math.log(2);
+
+    //calculate value to shift by (log base 2)
+	    
+    var shift_sat = Math.floor(Math.log(quant)/log2);
+    var shift_hue = Math.floor(Math.log(quant*quant)/log2);
+
+    //console.log("bit-shift sat = " + shift_sat);
+    //console.log("bit-shift hue = " + shift_hue);
+
+    var data = imageData.data;
+
+    //Loop through each pixel
+    var y,p;
+    for (y=0,p=0; y<imageObj.height; y++) {
+	var x;
+	for (x=0; x<imageObj.width; x++,p+=4) {
+	    // convert 4 byte data value into a colour pixel
+	    var rgb_c = new RGBColour(data[p],data[p+1],data[p+2],data[p+3]/255.0);
+	    var hsl = new rgb_c.getHSL();
+
+	    // express h,s and b in the range 0..1
+
+	    var h = hsl.h / 360.0;
+	    var s = hsl.s / 100.0;
+	    var b = hsl.l / 100.0;
+	    
+	    var result =    (Math.floor(h * (quant - 1)) << shift_hue) 
+		          | (Math.floor(s * (quant - 1)) << shift_sat) 
+		          |  Math.floor(b * (quant - 1));
+
+	    //number of opaque pixels
+	    var count = hsl.a;  // 'a' is naturally in the range 0..1
+		    
+	    //add to the total number of opaque pixels
+	    total += count;
+
+	    //add the frequency of each colour to the histogram
+	    outputArray[result] += count;                    
+	}
+    }
+
+    //Normalise the histogram, based on the number of opaque pixels
+    for (i=0; i<outputArray.length; i++) {
+	outputArray[i] = outputArray[i] / total;
+    }
+
+    return outputArray;
+}
+
+var flag_comparison_array = Array(2);
+var clicked_on_count = 0;
+
+function quantizedColourHistogramComparison(quant_colour_hist1,quant_colour_hist2) 
+{
+    // Assumes both histograms are of the same length
+
+    var i;
+    var quant_product = 0.0;
+
+    //Loop through and compare the histograms
+    for (i=0; i<quant_colour_hist1.length; i++) {
+	//take the overlap
+	quant_product += Math.min(quant_colour_hist1[i], quant_colour_hist2[i]);
+
+	// consider replacing with abs for difference
+    }
+
+    alert("Product for HSL histogram: " + quant_product);
+
+}
+
 
 function displayFlags(img_list,$displayDiv,$progressArea,$progressBar)
 {
     var img_list_len = img_list.length;
-    var show_progress = 5;
 
     if (img_list_len==0) {
@@ -43,25 +136,114 @@
 	
 	var imageObj = new Image();
-	imageObj.onload = function () {
+	imageObj.onload = function() {
 	    callback_count++;
 	    progressVal += progress_step;	
 	    $progressBar.progressbar('value',progressVal);
 	    
-	    //image1Data = drawImage(this, "canvas1");
-	    
 	    if (callback_count == img_list_len) {
 		if (img_list_len>show_progress) {
-		    $progressArea.slideUp();
+		    progressVal = 100;
+		    $progressBar.progressbar('value',progressVal);
+		    //$progressArea.slideUp();
+
+		    // Now move on and start computing colour histograms
+		    setTimeout(function() 
+			       {  computeFlagHistograms(img_list,$progressArea,$progressBar); }
+			       ,timeout_delay);
 		}
 	    }
 	};
+
+	imageObj.onclick = function() {
+	    // Store result of HSL quantization in the image object/tag
+	    if (!this.quantHSLHist) {
+		// Only need to compute this if it is not already stored in the object/tag
+		this.quantHSLHist = createHSLHistogram(this,16);
+		console.log(this.quantHSLHist);
+	    }
+	    flag_comparison_array[clicked_on_count] = this.quantHSLHist;
+
+	    clicked_on_count++;
+	    if (clicked_on_count==2) {
+		// trigger comparison
+		quantizedColourHistogramComparison(flag_comparison_array[0],flag_comparison_array[1]);
+		clicked_on_count=0;
+	    }
+	};
+	
 	
 	imageObj.src   = img_url;
 	imageObj.title = title;
-	
+	imageObj.id    = "flag-img-" + i;
+
 	$displayDiv.append(imageObj);
     }
 }
 
-
-
+function computeFlagHistogramChain(chain_count, img_list_len,
+				   progressVal, progress_step,
+				   $progressArea,$progressBar)
+{
+    var flag_id = "flag-img-" + chain_count;
+    console.log("Processing Image ID: " + flag_id);
+    var imageObj = document.getElementById(flag_id);
+
+    if (!imageObj.quantHSLHist) {
+	// Only need to compute this if it is not
+	// already stored in the object/tag
+	imageObj.quantHSLHist = createHSLHistogram(imageObj,16);
+	//console.log(imageObj.quantHSLHist);
+    }
+
+    if (chain_count < img_list_len-1) {
+	progressVal += progress_step;	
+	$progressBar.progressbar('value',progressVal);
+
+	setTimeout(function()
+		   { computeFlagHistogramChain(chain_count+1,img_list_len,
+					       progressVal, progress_step,
+					       $progressArea,$progressBar)
+			   }
+		   ,timeout_delay // any time delay causes break in 'rendering' thread, even 0!
+		   );
+
+    }
+    else {
+	$progressArea.find('span:first').text("Done.");
+	if (img_list_len>show_progress) {
+	    progressVal = 100;
+	    $progressBar.progressbar('value',progressVal);
+	    $progressArea.slideUp();
+	}
+    }
+}
+
+function computeFlagHistograms(img_list,$progressArea,$progressBar)
+{
+    var img_list_len = img_list.length;
+
+
+    if (img_list_len==0) {
+	$progressArea.find('span:first').text("Empty list: no computation needed.");
+	return;
+    }
+
+    $progressArea.find('span:first').text("Computing histograms:");
+    progressVal = 0;
+
+    if (img_list_len>show_progress) {
+	$progressArea.slideDown();
+    }
+
+    var progress_step = 100.0 / img_list_len;
+ 
+    // Start the chaining process
+    setTimeout(function() 
+	       { computeFlagHistogramChain(0,img_list_len,
+					   progressVal, progress_step,
+					   $progressArea,$progressBar)
+		       }
+	       ,timeout_delay // any time delay causes break in 'rendering' thread, even 0!
+	       );
+    
+}
