/* * upkg: tool for manipulating Unreal Tournament packages. * Copyright © 2012, 2020 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "pack.h" /* * Deserialize an IEEE 754 binary32 value in "little endian" (for whatever * that term is worth in this context). That is, when interpreted as a little * endian 32-bit unsigned integer: bit 31 is the sign, bits 30-23 are the * (biased) exponent, and bits 22-0 are the encoded part of the significand. * * The implementation is designed to be agnostic of the platform's actual * float type, but the conversion may be lossy if "float" is not itself a * binary32 format. NaN payloads are not preserved. */ float u_unpack_binary32_le(const unsigned char *buf) { unsigned long raw; long significand; int exponent; float result; raw = unpack_32_le(buf); exponent = (raw & 0x7f800000) >> 23; significand = (raw & 0x007fffff) >> 0; switch (exponent) { case 255: result = significand ? NAN : INFINITY; break; default: significand |= 0x00800000; /* fall through */ case 0: result = ldexpf(significand, exponent-126-24); } return copysignf(result, raw & 0x80000000 ? -1 : 1); }