Radiance .HDR format alters pixel value while saving.

  • 1
  • Problem
  • Updated 2 years ago
  • (Edited)
Photoshop's radiance HDR plugin
has precision problem while saving.

Loaded pixel value and saved pixel value
differs even if no pixel operation has done.
Photo of tam nik

tam nik

  • 4 Posts
  • 0 Reply Likes

Posted 2 years ago

  • 1
Photo of Chris Cox

Chris Cox

  • 20280 Posts
  • 812 Reply Likes
Yes, the Radiance RGBE format does not preserve full precision of pixel values. That is a well known issue with the Radiance file format.
Photo of tam nik

tam nik

  • 4 Posts
  • 0 Reply Likes
I surely see ahared-exponent format has a precision limit but
the format still has 8e8 precision.
And the stored pixel value should not changed
because the RGBE encoding is just a reverse of decoding.
See Radiance's source code for reference.

You can easily compare pixel value by HDRshop.
No other software breaks pixel
value by just load and save but Photoshop.

It's caused by Radiance.8BE's incorrect encode.
Photo of Chris Cox

Chris Cox

  • 20280 Posts
  • 812 Reply Likes
It has that precision in the channel with the greatest value. The precision for the other channels may not be as good because they all share the same exponent.

Photoshop matches Radiance's value conversions (verified that when I wrote the file format code).

But it is possible that there is a problem with the compiler or runtime libraries.

What OS version are you using?
Which specific version of Photoshop are you using?
Photo of tam nik

tam nik

  • 4 Posts
  • 0 Reply Likes
Thanks chris, but I know.

I also written a HDR toolkits for myself and found this problem.

you can easily reproduce this probelm by
just load an .HDR image and save .HDR image
and compare pixel value by HDRshop.

Photoshop saved image always gets smaller than the previous.

I tested this with Windows7, Windows8,
Photoshop CC 2015, Photoshop CS5, Photoshop CS6.

I used very common routine for encode :

float m = max( max( r,g ), b );
int e;
m = frexp( m, &e ) * 255.9999 / m;
RGBE[0] = r*m;
RGBE[1] = g*m;
RGBE[2] = b*m;
RGBE[3] = e;

and for decode :

float R = rgbe[0] * ldexp(1.0,rgbe[3]-(int)(128+8));
float G = rgbe[1] * ldexp(1.0,rgbe[3]-(int)(128+8));
float B = rgbe[2] * ldexp(1.0,rgbe[3]-(int)(128+8));

but the Radiance.8BE looked not like this.
Photo of Chris Cox

Chris Cox

  • 20280 Posts
  • 812 Reply Likes
You skipped a few preprocessing steps and conditions from the Radiance code.
See /ray/doc/notes/picture.format or /ray/src/common/color.c in the Radiance source.

Photoshop's code is not an exact match to Radiance, because the Radiance code cannot preserve a channel value of zero when another channel is non-zero.  Photoshop's code will preserve that zero value.  The values may differ by half the LSB because of this.  (yeah, I probably should call Greg Ward and get that fixed in Radiance as well)
(Edited)
Photo of tam nik

tam nik

  • 4 Posts
  • 0 Reply Likes
I think zero channel just goes to zero after encode at that Radiance's routine.

zero * any = zero even if it's rounded to uchar8.... isn't it?

Although, radiance code is now de-facto standard and
I think that making Photoshop's code
match exact to Radiance is better than modify the world.
Photo of Chris Cox

Chris Cox

  • 20280 Posts
  • 812 Reply Likes
Look at the Radiance code, where it adds an offset of 0.5 THEN multiplies by the scale.
That's a problem.
Again, your code doesn't match the Radiance code - look at the source and document I mentioned.