I've been working on this after the first version of it.
Didn't think I could let it go unfinished, did ya?
I used recursion to perform the sort on each sub array.
Code:
int w = 1024, h = 1024;//1 Mega-pixel image. Still pretty quick...
PImage data;// = new PImage(w,h);
PImage out;// = new PImage(w,h);
void setup() {
size(800,600);
data = createImage(w, h, ARGB);
out = createImage(w, h, ARGB);
noLoop();
}
void mouseClicked() {
int tmr = millis();
for (int i=0; i<data.pixels.length; i++) {
//Note: on my machine, when searching by numeric values (recursion depth is higher),
// ARGB takes about 10 times longer than RGB, at least at 1024x1024
//data.pixels[i] = (((int)random(0xffff))<<16) | ((int)random(0xffff));//Fills data with random ARGB
data.pixels[i] = ((int)random(0xffffff)) | 0xff000000;//Fills data with random RGB values
}
out.loadPixels();
out.pixels = sortArray(data.pixels, 0);
out.updatePixels();
println("Time (ms): " + (millis() - tmr));
redraw();
}
int[] sortArray(int[] tosort, int depth) {
int[][] contents = new int[256][];//256 levels for RGB/hue/brightness/etc
int[] counts = new int[256];//256 levels for RGB/hue/brightness/etc
int[] indexlist = new int[tosort.length];
int[] sorted = new int[tosort.length];
//Pass 1
int tx = 0;
for (int i=0; i<tosort.length; i++) {
/*
switch (depth) {//This sort sequence orders them by numeric value
case 0:
indexlist[i] = int(alpha(tosort[i]));//alpha
break;
case 1:
indexlist[i] = int(red(tosort[i]));//red
break;
case 2:
indexlist[i] = int(green(tosort[i]));//green
break;
case 3:
indexlist[i] = int(blue(tosort[i]));//blue
break;
default:
indexlist[i] = int(brightness(tosort[i]));//target
}
*/
switch (depth) {//This sort sequence orders them by hue then brightness
case 0:
indexlist[i] = int(hue(tosort[i]));//alpha
break;
case 1:
indexlist[i] = int(brightness(tosort[i]));//red
break;
default:
indexlist[i] = int(brightness(tosort[i]));//target
}
counts[indexlist[i]]++;//increment the count table
}
//Pass 2
for (int i=0; i<256; i++) {
contents[i] = new int[counts[i]];
}
//Pass 3
for (int i=0; i<tosort.length; i++) {
contents[ indexlist[i] ][ contents[indexlist[i]].length - counts[indexlist[i]] ] = tosort[i];
counts[indexlist[i]]--;//back down the count table
}
if ( (depth >= 0) && (depth < 4) ) {//=======================recursion call===============
for (int i=0; i<256; i++) {
if (contents[i].length > 0) {
switch (depth) {//Sort by hue then brightness
case 0:
contents[i] = sortArray(contents[i], 1);
break;
case 1:
//stop here
//contents[i] = sortArray(contents[i], 2);
break;
default:
//indexlist[i] = int(brightness(tosort[i]));//target
}
/*
switch (depth) {//Sort by numeric value
case 0:
contents[i] = sortArray(contents[i], 1);
break;
case 1:
contents[i] = sortArray(contents[i], 2);
break;
case 2:
contents[i] = sortArray(contents[i], 3);
break;
case 3:
//don't do it anymore
//contents[i] = sortArray(contents[i], -1);
break;
default:
//do nothing
}
*/
}
}
}
//Pass 4
int idx = 0;//Location to place into output
for (int i=0; i<contents.length; i++) {//outer array size
for (int d=0; d<contents[i].length; d++) {
sorted[idx] = contents[i][d];
idx++;
}
}
return sorted;
}
void draw() {
background(0,128,128);
image(out,0,0,600,600);
}