diff options
Diffstat (limited to 'intern/cycles/util/util_image_impl.h')
-rw-r--r-- | intern/cycles/util/util_image_impl.h | 68 |
1 files changed, 61 insertions, 7 deletions
diff --git a/intern/cycles/util/util_image_impl.h b/intern/cycles/util/util_image_impl.h index 73ecfda0855..a0f9c66f979 100644 --- a/intern/cycles/util/util_image_impl.h +++ b/intern/cycles/util/util_image_impl.h @@ -17,9 +17,10 @@ #ifndef __UTIL_IMAGE_IMPL_H__ #define __UTIL_IMAGE_IMPL_H__ -#include "util_algorithm.h" -#include "util_debug.h" -#include "util_image.h" +#include "util/util_algorithm.h" +#include "util/util_debug.h" +#include "util/util_half.h" +#include "util/util_image.h" CCL_NAMESPACE_BEGIN @@ -38,6 +39,52 @@ const T *util_image_read(const vector<T>& pixels, return &pixels[index]; } +/* Cast input pixel from unknown storage to float. */ +template<typename T> +inline float cast_to_float(T value); + +template<> +inline float cast_to_float(float value) +{ + return value; +} +template<> +inline float cast_to_float(uchar value) +{ + return (float)value / 255.0f; +} +template<> +inline float cast_to_float(half value) +{ + return half_to_float(value); +} + +/* Cast float value to output pixel type. */ +template<typename T> +inline T cast_from_float(float value); + +template<> +inline float cast_from_float(float value) +{ + return value; +} +template<> +inline uchar cast_from_float(float value) +{ + if(value < 0.0f) { + return 0; + } + else if(value > (1.0f - 0.5f / 255.0f)) { + return 255; + } + return (uchar)((255.0f * value) + 0.5f); +} +template<> +inline half cast_from_float(float value) +{ + return float_to_half(value); +} + template<typename T> void util_image_downscale_sample(const vector<T>& pixels, const size_t width, @@ -71,15 +118,22 @@ void util_image_downscale_sample(const vector<T>& pixels, components, nx, ny, nz); for(size_t k = 0; k < components; ++k) { - accum[k] += pixel[k]; + accum[k] += cast_to_float(pixel[k]); } ++count; } } } - const float inv_count = 1.0f / (float)count; - for(size_t k = 0; k < components; ++k) { - result[k] = T(accum[k] * inv_count); + if(count != 0) { + const float inv_count = 1.0f / (float)count; + for(size_t k = 0; k < components; ++k) { + result[k] = cast_from_float<T>(accum[k] * inv_count); + } + } + else { + for(size_t k = 0; k < components; ++k) { + result[k] = T(0.0f); + } } } |