/src/mozilla-central/gfx/angle/checkout/src/common/mathutil.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. |
3 | | // Use of this source code is governed by a BSD-style license that can be |
4 | | // found in the LICENSE file. |
5 | | // |
6 | | |
7 | | // mathutil.cpp: Math and bit manipulation functions. |
8 | | |
9 | | #include "common/mathutil.h" |
10 | | |
11 | | #include <algorithm> |
12 | | #include <math.h> |
13 | | |
14 | | namespace gl |
15 | | { |
16 | | |
17 | | namespace |
18 | | { |
19 | | |
20 | | struct RGB9E5Data |
21 | | { |
22 | | unsigned int R : 9; |
23 | | unsigned int G : 9; |
24 | | unsigned int B : 9; |
25 | | unsigned int E : 5; |
26 | | }; |
27 | | |
28 | | // B is the exponent bias (15) |
29 | | constexpr int g_sharedexp_bias = 15; |
30 | | |
31 | | // N is the number of mantissa bits per component (9) |
32 | | constexpr int g_sharedexp_mantissabits = 9; |
33 | | |
34 | | // Emax is the maximum allowed biased exponent value (31) |
35 | | constexpr int g_sharedexp_maxexponent = 31; |
36 | | |
37 | | constexpr float g_sharedexp_max = |
38 | | ((static_cast<float>(1 << g_sharedexp_mantissabits) - 1) / |
39 | | static_cast<float>(1 << g_sharedexp_mantissabits)) * |
40 | | static_cast<float>(1 << (g_sharedexp_maxexponent - g_sharedexp_bias)); |
41 | | |
42 | | } // anonymous namespace |
43 | | |
44 | | unsigned int convertRGBFloatsTo999E5(float red, float green, float blue) |
45 | 0 | { |
46 | 0 | const float red_c = std::max<float>(0, std::min(g_sharedexp_max, red)); |
47 | 0 | const float green_c = std::max<float>(0, std::min(g_sharedexp_max, green)); |
48 | 0 | const float blue_c = std::max<float>(0, std::min(g_sharedexp_max, blue)); |
49 | 0 |
|
50 | 0 | const float max_c = std::max<float>(std::max<float>(red_c, green_c), blue_c); |
51 | 0 | const float exp_p = std::max<float>(-g_sharedexp_bias - 1, floor(log(max_c))) + 1 + g_sharedexp_bias; |
52 | 0 | const int max_s = static_cast<int>(floor((max_c / (pow(2.0f, exp_p - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f)); |
53 | 0 | const int exp_s = static_cast<int>((max_s < pow(2.0f, g_sharedexp_mantissabits)) ? exp_p : exp_p + 1); |
54 | 0 |
|
55 | 0 | RGB9E5Data output; |
56 | 0 | output.R = static_cast<unsigned int>(floor((red_c / (pow(2.0f, exp_s - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f)); |
57 | 0 | output.G = static_cast<unsigned int>(floor((green_c / (pow(2.0f, exp_s - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f)); |
58 | 0 | output.B = static_cast<unsigned int>(floor((blue_c / (pow(2.0f, exp_s - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f)); |
59 | 0 | output.E = exp_s; |
60 | 0 |
|
61 | 0 | return bitCast<unsigned int>(output); |
62 | 0 | } |
63 | | |
64 | | void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue) |
65 | 0 | { |
66 | 0 | const RGB9E5Data *inputData = reinterpret_cast<const RGB9E5Data*>(&input); |
67 | 0 |
|
68 | 0 | *red = inputData->R * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits); |
69 | 0 | *green = inputData->G * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits); |
70 | 0 | *blue = inputData->B * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits); |
71 | 0 | } |
72 | | |
73 | | } // namespace gl |