1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * This file is part of FFmpeg. 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12cabdff1aSopenharmony_ci * Lesser General Public License for more details. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17cabdff1aSopenharmony_ci */ 18cabdff1aSopenharmony_ci 19cabdff1aSopenharmony_ci#ifndef AVCODEC_FLOAT2HALF_H 20cabdff1aSopenharmony_ci#define AVCODEC_FLOAT2HALF_H 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include <stdint.h> 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_cistatic void float2half_tables(uint16_t *basetable, uint8_t *shifttable) 25cabdff1aSopenharmony_ci{ 26cabdff1aSopenharmony_ci for (int i = 0; i < 256; i++) { 27cabdff1aSopenharmony_ci int e = i - 127; 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci if (e < -24) { // Very small numbers map to zero 30cabdff1aSopenharmony_ci basetable[i|0x000] = 0x0000; 31cabdff1aSopenharmony_ci basetable[i|0x100] = 0x8000; 32cabdff1aSopenharmony_ci shifttable[i|0x000] = 24; 33cabdff1aSopenharmony_ci shifttable[i|0x100] = 24; 34cabdff1aSopenharmony_ci } else if (e < -14) { // Small numbers map to denorms 35cabdff1aSopenharmony_ci basetable[i|0x000] = (0x0400>>(-e-14)); 36cabdff1aSopenharmony_ci basetable[i|0x100] = (0x0400>>(-e-14)) | 0x8000; 37cabdff1aSopenharmony_ci shifttable[i|0x000] = -e-1; 38cabdff1aSopenharmony_ci shifttable[i|0x100] = -e-1; 39cabdff1aSopenharmony_ci } else if (e <= 15) { // Normal numbers just lose precision 40cabdff1aSopenharmony_ci basetable[i|0x000] = ((e + 15) << 10); 41cabdff1aSopenharmony_ci basetable[i|0x100] = ((e + 15) << 10) | 0x8000; 42cabdff1aSopenharmony_ci shifttable[i|0x000] = 13; 43cabdff1aSopenharmony_ci shifttable[i|0x100] = 13; 44cabdff1aSopenharmony_ci } else if (e < 128) { // Large numbers map to Infinity 45cabdff1aSopenharmony_ci basetable[i|0x000] = 0x7C00; 46cabdff1aSopenharmony_ci basetable[i|0x100] = 0xFC00; 47cabdff1aSopenharmony_ci shifttable[i|0x000] = 24; 48cabdff1aSopenharmony_ci shifttable[i|0x100] = 24; 49cabdff1aSopenharmony_ci } else { // Infinity and NaN's stay Infinity and NaN's 50cabdff1aSopenharmony_ci basetable[i|0x000] = 0x7C00; 51cabdff1aSopenharmony_ci basetable[i|0x100] = 0xFC00; 52cabdff1aSopenharmony_ci shifttable[i|0x000] = 13; 53cabdff1aSopenharmony_ci shifttable[i|0x100] = 13; 54cabdff1aSopenharmony_ci } 55cabdff1aSopenharmony_ci } 56cabdff1aSopenharmony_ci} 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_cistatic uint16_t float2half(uint32_t f, uint16_t *basetable, uint8_t *shifttable) 59cabdff1aSopenharmony_ci{ 60cabdff1aSopenharmony_ci uint16_t h; 61cabdff1aSopenharmony_ci 62cabdff1aSopenharmony_ci h = basetable[(f >> 23) & 0x1ff] + ((f & 0x007fffff) >> shifttable[(f >> 23) & 0x1ff]); 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci return h; 65cabdff1aSopenharmony_ci} 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_ci#endif /* AVCODEC_FLOAT2HALF_H */ 68