---
Update - I've got it figured out now, I should have been using gluUnProject:
FloatBuffer fb;
fb = BufferUtil.newFloatBuffer(width*height);
gl.glReadPixels(0, 0, width, height, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, fb);
fb.rewind();
int viewport[] = new int[4];
double[] proj=new double[16];
double[] model=new double[16];
gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
gl.glGetDoublev(GL.GL_PROJECTION_MATRIX,proj,0);
gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX,model,0);
...
for(int i...
for (int j...
...
glu.gluUnProject(i,height-j,rawd, model,0,proj,0,viewport,0,pos,0);
float d = (float)-pos[2];
After all that depth d will be linear and in proper world coordinates.