I found this site with a neat GLSL fragment shader
http://www.iquilezles.org/www/articles/texture/texture.htm : it implements a way to enlarge a low resolution, high contrast image obtaining better pixels definition.
It's very clever: when a low resolution image is rendered you usually get linear interpolation between the color values, which looks pretty bad in high contrast pictures (star shaped artifacts). This filter alters the texture coordinate that you are sampling so to reduce and smooth the transition between the color samples. You can apply it to your image using the code below where "texture" is the image, and "resol" is a vector of the picture pixel size (width , height).
To give you an idea I attach a sample with bilinear filtered image on the left, shader filtered image in the middle and original high resolution image on the right (the effect is more visible on low res images so I downsampled the image before)
uniform sampler2D texture;
uniform vec2 resol;
void main()
{
vec2 uv = gl_TexCoord[0].xy;
uv = uv*resol + 0.5;
vec2 i = floor(uv);
vec2 f = uv - i;
f = f*f*f*(f*(f*6.0-15.0)+10.0);
uv = i + f;
uv = (uv - 0.5)/resol;
gl_FragColor = texture2D(texture, uv);
}
By editing the f = f*f*f*(f*(f*6.0-15.0)+10.0); part you can have a sharper effect or a different transition shape.