Skip to content

Commit

Permalink
avutil/half2float: adjust conversion of NaN
Browse files Browse the repository at this point in the history
IEEE-754 differentiates two different kind of NaNs.
Quiet and Signaling ones. They are differentiated by the MSB of the
mantissa.

For whatever reason, actual hardware conversion of half to single always
sets the signaling bit to 1 if the mantissa is != 0, and to 0 if it's 0.
So our code has to follow suite or fate-testing hardware float16 will be
impossible.
  • Loading branch information
BtbN committed Aug 19, 2022
1 parent b429252 commit cb8ad00
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 3 deletions.
2 changes: 1 addition & 1 deletion libavcodec/exr.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ typedef struct EXRContext {
float gamma;
union av_intfloat32 gamma_table[65536];

uint32_t mantissatable[2048];
uint32_t mantissatable[3072];
uint32_t exponenttable[64];
uint16_t offsettable[64];
} EXRContext;
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/pnm.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ typedef struct PNMContext {
int half;
float scale;

uint32_t mantissatable[2048];
uint32_t mantissatable[3072];
uint32_t exponenttable[64];
uint16_t offsettable[64];
} PNMContext;
Expand Down
5 changes: 5 additions & 0 deletions libavutil/half2float.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ static void half2float_table(uint32_t *mantissatable, uint32_t *exponenttable,
mantissatable[i] = convertmantissa(i);
for (int i = 1024; i < 2048; i++)
mantissatable[i] = 0x38000000UL + ((i - 1024) << 13UL);
for (int i = 2048; i < 3072; i++)
mantissatable[i] = mantissatable[i - 1024] | 0x400000UL;
mantissatable[2048] = mantissatable[1024];

exponenttable[0] = 0;
for (int i = 1; i < 31; i++)
Expand All @@ -58,7 +61,9 @@ static void half2float_table(uint32_t *mantissatable, uint32_t *exponenttable,
offsettable[0] = 0;
for (int i = 1; i < 64; i++)
offsettable[i] = 1024;
offsettable[31] = 2048;
offsettable[32] = 0;
offsettable[63] = 2048;
}

static uint32_t half2float(uint16_t h, const uint32_t *mantissatable, const uint32_t *exponenttable,
Expand Down
2 changes: 1 addition & 1 deletion tests/ref/fate/exr-rgb-scanline-zip-half-0x0-0xFFFF
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
#codec_id 0: rawvideo
#dimensions 0: 256x256
#sar 0: 1/1
0, 0, 0, 1, 786432, 0x1445e411
0, 0, 0, 1, 786432, 0xce9be2be

0 comments on commit cb8ad00

Please sign in to comment.