Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/render/colorspace.cpp')
-rw-r--r--intern/cycles/render/colorspace.cpp398
1 files changed, 0 insertions, 398 deletions
diff --git a/intern/cycles/render/colorspace.cpp b/intern/cycles/render/colorspace.cpp
deleted file mode 100644
index 3842f8e4726..00000000000
--- a/intern/cycles/render/colorspace.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Copyright 2011-2013 Blender Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "render/colorspace.h"
-
-#include "util/util_color.h"
-#include "util/util_half.h"
-#include "util/util_image.h"
-#include "util/util_logging.h"
-#include "util/util_math.h"
-#include "util/util_thread.h"
-#include "util/util_vector.h"
-
-#ifdef WITH_OCIO
-# include <OpenColorIO/OpenColorIO.h>
-namespace OCIO = OCIO_NAMESPACE;
-#endif
-
-CCL_NAMESPACE_BEGIN
-
-/* Builtin colorspaces. */
-ustring u_colorspace_auto;
-ustring u_colorspace_raw("__builtin_raw");
-ustring u_colorspace_srgb("__builtin_srgb");
-
-/* Cached data. */
-#ifdef WITH_OCIO
-static thread_mutex cache_colorspaces_mutex;
-static thread_mutex cache_processors_mutex;
-static unordered_map<ustring, ustring, ustringHash> cached_colorspaces;
-static unordered_map<ustring, OCIO::ConstProcessorRcPtr, ustringHash> cached_processors;
-#endif
-
-ColorSpaceProcessor *ColorSpaceManager::get_processor(ustring colorspace)
-{
-#ifdef WITH_OCIO
- /* Only use this for OpenColorIO color spaces, not the builtin ones. */
- assert(colorspace != u_colorspace_srgb && colorspace != u_colorspace_auto);
-
- if (colorspace == u_colorspace_raw) {
- return NULL;
- }
-
- OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
- if (!config) {
- return NULL;
- }
-
- /* Cache processor until free_memory(), memory overhead is expected to be
- * small and the processor is likely to be reused. */
- thread_scoped_lock cache_processors_lock(cache_processors_mutex);
- if (cached_processors.find(colorspace) == cached_processors.end()) {
- try {
- cached_processors[colorspace] = config->getProcessor(colorspace.c_str(), "scene_linear");
- }
- catch (OCIO::Exception &exception) {
- cached_processors[colorspace] = OCIO::ConstProcessorRcPtr();
- VLOG(1) << "Colorspace " << colorspace.c_str()
- << " can't be converted to scene_linear: " << exception.what();
- }
- }
-
- const OCIO::Processor *processor = cached_processors[colorspace].get();
- return (ColorSpaceProcessor *)processor;
-#else
- /* No OpenColorIO. */
- (void)colorspace;
- return NULL;
-#endif
-}
-
-bool ColorSpaceManager::colorspace_is_data(ustring colorspace)
-{
- if (colorspace == u_colorspace_auto || colorspace == u_colorspace_raw ||
- colorspace == u_colorspace_srgb) {
- return false;
- }
-
-#ifdef WITH_OCIO
- OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
- if (!config) {
- return false;
- }
-
- try {
- OCIO::ConstColorSpaceRcPtr space = config->getColorSpace(colorspace.c_str());
- return space && space->isData();
- }
- catch (OCIO::Exception &) {
- return false;
- }
-#else
- return false;
-#endif
-}
-
-ustring ColorSpaceManager::detect_known_colorspace(ustring colorspace,
- const char *file_format,
- bool is_float)
-{
- if (colorspace == u_colorspace_auto) {
- /* Auto detect sRGB or raw if none specified. */
- if (is_float) {
- bool srgb = (colorspace == "sRGB" || colorspace == "GammaCorrected" ||
- (colorspace.empty() &&
- (strcmp(file_format, "png") == 0 || strcmp(file_format, "tiff") == 0 ||
- strcmp(file_format, "dpx") == 0 || strcmp(file_format, "jpeg2000") == 0)));
- return srgb ? u_colorspace_srgb : u_colorspace_raw;
- }
- else {
- return u_colorspace_srgb;
- }
- }
- else if (colorspace == u_colorspace_srgb || colorspace == u_colorspace_raw) {
- /* Builtin colorspaces. */
- return colorspace;
- }
- else {
- /* Use OpenColorIO. */
-#ifdef WITH_OCIO
- {
- thread_scoped_lock cache_lock(cache_colorspaces_mutex);
- /* Cached lookup. */
- if (cached_colorspaces.find(colorspace) != cached_colorspaces.end()) {
- return cached_colorspaces[colorspace];
- }
- }
-
- /* Detect if it matches a simple builtin colorspace. */
- bool is_scene_linear, is_srgb;
- is_builtin_colorspace(colorspace, is_scene_linear, is_srgb);
-
- thread_scoped_lock cache_lock(cache_colorspaces_mutex);
- if (is_scene_linear) {
- VLOG(1) << "Colorspace " << colorspace.string() << " is no-op";
- cached_colorspaces[colorspace] = u_colorspace_raw;
- return u_colorspace_raw;
- }
- else if (is_srgb) {
- VLOG(1) << "Colorspace " << colorspace.string() << " is sRGB";
- cached_colorspaces[colorspace] = u_colorspace_srgb;
- return u_colorspace_srgb;
- }
-
- /* Verify if we can convert from the requested color space. */
- if (!get_processor(colorspace)) {
- OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
- if (!config || !config->getColorSpace(colorspace.c_str())) {
- VLOG(1) << "Colorspace " << colorspace.c_str() << " not found, using raw instead";
- }
- else {
- VLOG(1) << "Colorspace " << colorspace.c_str()
- << " can't be converted to scene_linear, using raw instead";
- }
- cached_colorspaces[colorspace] = u_colorspace_raw;
- return u_colorspace_raw;
- }
-
- /* Convert to/from colorspace with OpenColorIO. */
- VLOG(1) << "Colorspace " << colorspace.string() << " handled through OpenColorIO";
- cached_colorspaces[colorspace] = colorspace;
- return colorspace;
-#else
- VLOG(1) << "Colorspace " << colorspace.c_str() << " not available, built without OpenColorIO";
- return u_colorspace_raw;
-#endif
- }
-}
-
-void ColorSpaceManager::is_builtin_colorspace(ustring colorspace,
- bool &is_scene_linear,
- bool &is_srgb)
-{
-#ifdef WITH_OCIO
- const OCIO::Processor *processor = (const OCIO::Processor *)get_processor(colorspace);
- if (!processor) {
- is_scene_linear = false;
- is_srgb = false;
- return;
- }
-
- OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
- is_scene_linear = true;
- is_srgb = true;
- for (int i = 0; i < 256; i++) {
- float v = i / 255.0f;
-
- float cR[3] = {v, 0, 0};
- float cG[3] = {0, v, 0};
- float cB[3] = {0, 0, v};
- float cW[3] = {v, v, v};
- device_processor->applyRGB(cR);
- device_processor->applyRGB(cG);
- device_processor->applyRGB(cB);
- device_processor->applyRGB(cW);
-
- /* Make sure that there is no channel crosstalk. */
- if (fabsf(cR[1]) > 1e-5f || fabsf(cR[2]) > 1e-5f || fabsf(cG[0]) > 1e-5f ||
- fabsf(cG[2]) > 1e-5f || fabsf(cB[0]) > 1e-5f || fabsf(cB[1]) > 1e-5f) {
- is_scene_linear = false;
- is_srgb = false;
- break;
- }
- /* Make sure that the three primaries combine linearly. */
- if (!compare_floats(cR[0], cW[0], 1e-6f, 64) || !compare_floats(cG[1], cW[1], 1e-6f, 64) ||
- !compare_floats(cB[2], cW[2], 1e-6f, 64)) {
- is_scene_linear = false;
- is_srgb = false;
- break;
- }
- /* Make sure that the three channels behave identically. */
- if (!compare_floats(cW[0], cW[1], 1e-6f, 64) || !compare_floats(cW[1], cW[2], 1e-6f, 64)) {
- is_scene_linear = false;
- is_srgb = false;
- break;
- }
-
- float out_v = average(make_float3(cW[0], cW[1], cW[2]));
- if (!compare_floats(v, out_v, 1e-6f, 64)) {
- is_scene_linear = false;
- }
- if (!compare_floats(color_srgb_to_linear(v), out_v, 1e-6f, 64)) {
- is_srgb = false;
- }
- }
-#else
- (void)colorspace;
- is_scene_linear = false;
- is_srgb = false;
-#endif
-}
-
-#ifdef WITH_OCIO
-
-template<typename T> inline float4 cast_to_float4(T *data)
-{
- return make_float4(util_image_cast_to_float(data[0]),
- util_image_cast_to_float(data[1]),
- util_image_cast_to_float(data[2]),
- util_image_cast_to_float(data[3]));
-}
-
-template<typename T> inline void cast_from_float4(T *data, float4 value)
-{
- data[0] = util_image_cast_from_float<T>(value.x);
- data[1] = util_image_cast_from_float<T>(value.y);
- data[2] = util_image_cast_from_float<T>(value.z);
- data[3] = util_image_cast_from_float<T>(value.w);
-}
-
-/* Slower versions for other all data types, which needs to convert to float and back. */
-template<typename T, bool compress_as_srgb = false>
-inline void processor_apply_pixels(const OCIO::Processor *processor, T *pixels, size_t num_pixels)
-{
- /* TODO: implement faster version for when we know the conversion
- * is a simple matrix transform between linear spaces. In that case
- * un-premultiply is not needed. */
- OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
-
- /* Process large images in chunks to keep temporary memory requirement down. */
- const size_t chunk_size = std::min((size_t)(16 * 1024 * 1024), num_pixels);
- vector<float4> float_pixels(chunk_size);
-
- for (size_t j = 0; j < num_pixels; j += chunk_size) {
- size_t width = std::min(chunk_size, num_pixels - j);
-
- for (size_t i = 0; i < width; i++) {
- float4 value = cast_to_float4(pixels + 4 * (j + i));
-
- if (!(value.w <= 0.0f || value.w == 1.0f)) {
- float inv_alpha = 1.0f / value.w;
- value.x *= inv_alpha;
- value.y *= inv_alpha;
- value.z *= inv_alpha;
- }
-
- float_pixels[i] = value;
- }
-
- OCIO::PackedImageDesc desc((float *)float_pixels.data(), width, 1, 4);
- device_processor->apply(desc);
-
- for (size_t i = 0; i < width; i++) {
- float4 value = float_pixels[i];
-
- if (compress_as_srgb) {
- value = color_linear_to_srgb_v4(value);
- }
-
- if (!(value.w <= 0.0f || value.w == 1.0f)) {
- value.x *= value.w;
- value.y *= value.w;
- value.z *= value.w;
- }
-
- cast_from_float4(pixels + 4 * (j + i), value);
- }
- }
-}
-#endif
-
-template<typename T>
-void ColorSpaceManager::to_scene_linear(ustring colorspace,
- T *pixels,
- size_t num_pixels,
- bool compress_as_srgb)
-{
-#ifdef WITH_OCIO
- const OCIO::Processor *processor = (const OCIO::Processor *)get_processor(colorspace);
-
- if (processor) {
- if (compress_as_srgb) {
- /* Compress output as sRGB. */
- processor_apply_pixels<T, true>(processor, pixels, num_pixels);
- }
- else {
- /* Write output as scene linear directly. */
- processor_apply_pixels<T>(processor, pixels, num_pixels);
- }
- }
-#else
- (void)colorspace;
- (void)pixels;
- (void)num_pixels;
- (void)compress_as_srgb;
-#endif
-}
-
-void ColorSpaceManager::to_scene_linear(ColorSpaceProcessor *processor_,
- float *pixel,
- int channels)
-{
-#ifdef WITH_OCIO
- const OCIO::Processor *processor = (const OCIO::Processor *)processor_;
-
- if (processor) {
- OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
- if (channels == 3) {
- device_processor->applyRGB(pixel);
- }
- else if (channels == 4) {
- if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
- /* Fast path for RGBA. */
- device_processor->applyRGB(pixel);
- }
- else {
- /* Un-associate and associate alpha since color management should not
- * be affected by transparency. */
- float alpha = pixel[3];
- float inv_alpha = 1.0f / alpha;
-
- pixel[0] *= inv_alpha;
- pixel[1] *= inv_alpha;
- pixel[2] *= inv_alpha;
-
- device_processor->applyRGB(pixel);
-
- pixel[0] *= alpha;
- pixel[1] *= alpha;
- pixel[2] *= alpha;
- }
- }
- }
-#else
- (void)processor_;
- (void)pixel;
- (void)channels;
-#endif
-}
-
-void ColorSpaceManager::free_memory()
-{
-#ifdef WITH_OCIO
- map_free_memory(cached_colorspaces);
- map_free_memory(cached_processors);
-#endif
-}
-
-/* Template instantiations so we don't have to inline functions. */
-template void ColorSpaceManager::to_scene_linear(ustring, uchar *, size_t, bool);
-template void ColorSpaceManager::to_scene_linear(ustring, ushort *, size_t, bool);
-template void ColorSpaceManager::to_scene_linear(ustring, half *, size_t, bool);
-template void ColorSpaceManager::to_scene_linear(ustring, float *, size_t, bool);
-
-CCL_NAMESPACE_END