Cycles: support loading images from arbitrary OpenColorIO color space
[blender.git] / intern / cycles / render / nodes.cpp
index 35e9f8d..6e86643 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include "render/colorspace.h"
 #include "render/film.h"
 #include "render/image.h"
 #include "render/integrator.h"
@@ -207,11 +208,7 @@ NODE_DEFINE(ImageTextureNode)
   TEXTURE_MAPPING_DEFINE(ImageTextureNode);
 
   SOCKET_STRING(filename, "Filename", ustring());
-
-  static NodeEnum color_space_enum;
-  color_space_enum.insert("none", NODE_COLOR_SPACE_NONE);
-  color_space_enum.insert("color", NODE_COLOR_SPACE_COLOR);
-  SOCKET_ENUM(color_space, "Color Space", color_space_enum, NODE_COLOR_SPACE_COLOR);
+  SOCKET_STRING(colorspace, "Colorspace", u_colorspace_auto);
 
   SOCKET_BOOLEAN(use_alpha, "Use Alpha", true);
 
@@ -250,7 +247,8 @@ ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(node_type)
   image_manager = NULL;
   slot = -1;
   is_float = -1;
-  is_linear = false;
+  compress_as_srgb = false;
+  colorspace = u_colorspace_raw;
   builtin_data = NULL;
   animated = false;
 }
@@ -259,7 +257,7 @@ ImageTextureNode::~ImageTextureNode()
 {
   if (image_manager) {
     image_manager->remove_image(
-        filename.string(), builtin_data, interpolation, extension, use_alpha);
+        filename.string(), builtin_data, interpolation, extension, use_alpha, colorspace);
   }
 }
 
@@ -269,7 +267,8 @@ ShaderNode *ImageTextureNode::clone() const
   node->image_manager = NULL;
   node->slot = -1;
   node->is_float = -1;
-  node->is_linear = false;
+  node->compress_as_srgb = false;
+  node->colorspace = u_colorspace_raw;
   return node;
 }
 
@@ -304,13 +303,14 @@ void ImageTextureNode::compile(SVMCompiler &compiler)
                                     interpolation,
                                     extension,
                                     use_alpha,
+                                    colorspace,
                                     metadata);
     is_float = metadata.is_float;
-    is_linear = metadata.is_linear;
+    compress_as_srgb = metadata.compress_as_srgb;
+    colorspace = metadata.colorspace;
   }
 
   if (slot != -1) {
-    int srgb = (is_linear || color_space != NODE_COLOR_SPACE_COLOR) ? 0 : 1;
     int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
 
     if (projection != NODE_IMAGE_PROJ_BOX) {
@@ -319,7 +319,7 @@ void ImageTextureNode::compile(SVMCompiler &compiler)
                         compiler.encode_uchar4(vector_offset,
                                                compiler.stack_assign_if_linked(color_out),
                                                compiler.stack_assign_if_linked(alpha_out),
-                                               srgb),
+                                               compress_as_srgb),
                         projection);
     }
     else {
@@ -328,7 +328,7 @@ void ImageTextureNode::compile(SVMCompiler &compiler)
                         compiler.encode_uchar4(vector_offset,
                                                compiler.stack_assign_if_linked(color_out),
                                                compiler.stack_assign_if_linked(alpha_out),
-                                               srgb),
+                                               compress_as_srgb),
                         __float_as_int(projection_blend));
     }
 
@@ -358,7 +358,7 @@ void ImageTextureNode::compile(OSLCompiler &compiler)
   if (is_float == -1) {
     ImageMetaData metadata;
     if (builtin_data == NULL) {
-      image_manager->get_image_metadata(filename.string(), NULL, metadata);
+      image_manager->get_image_metadata(filename.string(), NULL, colorspace, metadata);
     }
     else {
       slot = image_manager->add_image(filename.string(),
@@ -368,17 +368,22 @@ void ImageTextureNode::compile(OSLCompiler &compiler)
                                       interpolation,
                                       extension,
                                       use_alpha,
+                                      colorspace,
                                       metadata);
     }
     is_float = metadata.is_float;
-    is_linear = metadata.is_linear;
+    compress_as_srgb = metadata.compress_as_srgb;
+    colorspace = metadata.colorspace;
   }
 
-  compiler.parameter_texture("filename", filename, slot);
-  if (is_linear || color_space != NODE_COLOR_SPACE_COLOR)
-    compiler.parameter("color_space", "linear");
-  else
-    compiler.parameter("color_space", "sRGB");
+  if (slot == -1) {
+    compiler.parameter_texture("filename", filename, colorspace);
+  }
+  else {
+    compiler.parameter_texture("filename", slot);
+  }
+
+  compiler.parameter("color_space", (compress_as_srgb) ? "sRGB" : "linear");
   compiler.parameter(this, "projection");
   compiler.parameter(this, "projection_blend");
   compiler.parameter("is_float", is_float);
@@ -398,11 +403,7 @@ NODE_DEFINE(EnvironmentTextureNode)
   TEXTURE_MAPPING_DEFINE(EnvironmentTextureNode);
 
   SOCKET_STRING(filename, "Filename", ustring());
-
-  static NodeEnum color_space_enum;
-  color_space_enum.insert("none", NODE_COLOR_SPACE_NONE);
-  color_space_enum.insert("color", NODE_COLOR_SPACE_COLOR);
-  SOCKET_ENUM(color_space, "Color Space", color_space_enum, NODE_COLOR_SPACE_COLOR);
+  SOCKET_STRING(colorspace, "Colorspace", u_colorspace_auto);
 
   SOCKET_BOOLEAN(use_alpha, "Use Alpha", true);
 
@@ -431,7 +432,8 @@ EnvironmentTextureNode::EnvironmentTextureNode() : ImageSlotTextureNode(node_typ
   image_manager = NULL;
   slot = -1;
   is_float = -1;
-  is_linear = false;
+  compress_as_srgb = false;
+  colorspace = u_colorspace_raw;
   builtin_data = NULL;
   animated = false;
 }
@@ -440,7 +442,7 @@ EnvironmentTextureNode::~EnvironmentTextureNode()
 {
   if (image_manager) {
     image_manager->remove_image(
-        filename.string(), builtin_data, interpolation, EXTENSION_REPEAT, use_alpha);
+        filename.string(), builtin_data, interpolation, EXTENSION_REPEAT, use_alpha, colorspace);
   }
 }
 
@@ -450,7 +452,8 @@ ShaderNode *EnvironmentTextureNode::clone() const
   node->image_manager = NULL;
   node->slot = -1;
   node->is_float = -1;
-  node->is_linear = false;
+  node->compress_as_srgb = false;
+  node->colorspace = u_colorspace_raw;
   return node;
 }
 
@@ -483,13 +486,14 @@ void EnvironmentTextureNode::compile(SVMCompiler &compiler)
                                     interpolation,
                                     EXTENSION_REPEAT,
                                     use_alpha,
+                                    colorspace,
                                     metadata);
     is_float = metadata.is_float;
-    is_linear = metadata.is_linear;
+    compress_as_srgb = metadata.compress_as_srgb;
+    colorspace = metadata.colorspace;
   }
 
   if (slot != -1) {
-    int srgb = (is_linear || color_space != NODE_COLOR_SPACE_COLOR) ? 0 : 1;
     int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
 
     compiler.add_node(NODE_TEX_ENVIRONMENT,
@@ -497,7 +501,7 @@ void EnvironmentTextureNode::compile(SVMCompiler &compiler)
                       compiler.encode_uchar4(vector_offset,
                                              compiler.stack_assign_if_linked(color_out),
                                              compiler.stack_assign_if_linked(alpha_out),
-                                             srgb),
+                                             compress_as_srgb),
                       projection);
 
     tex_mapping.compile_end(compiler, vector_in, vector_offset);
@@ -529,7 +533,7 @@ void EnvironmentTextureNode::compile(OSLCompiler &compiler)
   if (is_float == -1) {
     ImageMetaData metadata;
     if (builtin_data == NULL) {
-      image_manager->get_image_metadata(filename.string(), NULL, metadata);
+      image_manager->get_image_metadata(filename.string(), NULL, colorspace, metadata);
     }
     else {
       slot = image_manager->add_image(filename.string(),
@@ -539,19 +543,23 @@ void EnvironmentTextureNode::compile(OSLCompiler &compiler)
                                       interpolation,
                                       EXTENSION_REPEAT,
                                       use_alpha,
+                                      colorspace,
                                       metadata);
     }
     is_float = metadata.is_float;
-    is_linear = metadata.is_linear;
+    compress_as_srgb = metadata.compress_as_srgb;
+    colorspace = metadata.colorspace;
   }
 
-  compiler.parameter_texture("filename", filename, slot);
-  compiler.parameter(this, "projection");
-  if (is_linear || color_space != NODE_COLOR_SPACE_COLOR)
-    compiler.parameter("color_space", "linear");
-  else
-    compiler.parameter("color_space", "sRGB");
+  if (slot == -1) {
+    compiler.parameter_texture("filename", filename, colorspace);
+  }
+  else {
+    compiler.parameter_texture("filename", slot);
+  }
 
+  compiler.parameter(this, "projection");
+  compiler.parameter("color_space", (compress_as_srgb) ? "sRGB" : "linear");
   compiler.parameter(this, "interpolation");
   compiler.parameter("is_float", is_float);
   compiler.parameter("use_alpha", !alpha_out->links.empty());
@@ -1467,7 +1475,7 @@ PointDensityTextureNode::~PointDensityTextureNode()
 {
   if (image_manager) {
     image_manager->remove_image(
-        filename.string(), builtin_data, interpolation, EXTENSION_CLIP, true);
+        filename.string(), builtin_data, interpolation, EXTENSION_CLIP, true, ustring());
   }
 }
 
@@ -1491,8 +1499,15 @@ void PointDensityTextureNode::add_image()
 {
   if (slot == -1) {
     ImageMetaData metadata;
-    slot = image_manager->add_image(
-        filename.string(), builtin_data, false, 0, interpolation, EXTENSION_CLIP, true, metadata);
+    slot = image_manager->add_image(filename.string(),
+                                    builtin_data,
+                                    false,
+                                    0,
+                                    interpolation,
+                                    EXTENSION_CLIP,
+                                    true,
+                                    u_colorspace_raw,
+                                    metadata);
   }
 }
 
@@ -1551,7 +1566,7 @@ void PointDensityTextureNode::compile(OSLCompiler &compiler)
   if (use_density || use_color) {
     add_image();
 
-    compiler.parameter_texture("filename", ustring(), slot);
+    compiler.parameter_texture("filename", slot);
     if (space == NODE_TEX_VOXEL_SPACE_WORLD) {
       compiler.parameter("mapping", tfm);
       compiler.parameter("use_mapping", 1);