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:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /intern/cycles/render/image.cpp
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'intern/cycles/render/image.cpp')
-rw-r--r--intern/cycles/render/image.cpp1741
1 files changed, 838 insertions, 903 deletions
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 1edd5865836..ae219e912e0 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -27,7 +27,7 @@
#include "util/util_unique_ptr.h"
#ifdef WITH_OSL
-#include <OSL/oslexec.h>
+# include <OSL/oslexec.h>
#endif
CCL_NAMESPACE_BEGIN
@@ -37,15 +37,15 @@ namespace {
/* Some helpers to silence warning in templated function. */
bool isfinite(uchar /*value*/)
{
- return true;
+ return true;
}
bool isfinite(half /*value*/)
{
- return true;
+ return true;
}
-bool isfinite(uint16_t /*value*/)
+bool isfinite(uint16_t /*value*/)
{
- return true;
+ return true;
}
/* The lower three bits of a device texture slot number indicate its type.
@@ -54,946 +54,888 @@ bool isfinite(uint16_t /*value*/)
*/
int type_index_to_flattened_slot(int slot, ImageDataType type)
{
- return (slot << IMAGE_DATA_TYPE_SHIFT) | (type);
+ return (slot << IMAGE_DATA_TYPE_SHIFT) | (type);
}
int flattened_slot_to_type_index(int flat_slot, ImageDataType *type)
{
- *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK);
- return flat_slot >> IMAGE_DATA_TYPE_SHIFT;
+ *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK);
+ return flat_slot >> IMAGE_DATA_TYPE_SHIFT;
}
-const char* name_from_type(ImageDataType type)
+const char *name_from_type(ImageDataType type)
{
- switch(type) {
- case IMAGE_DATA_TYPE_FLOAT4: return "float4";
- case IMAGE_DATA_TYPE_BYTE4: return "byte4";
- case IMAGE_DATA_TYPE_HALF4: return "half4";
- case IMAGE_DATA_TYPE_FLOAT: return "float";
- case IMAGE_DATA_TYPE_BYTE: return "byte";
- case IMAGE_DATA_TYPE_HALF: return "half";
- case IMAGE_DATA_TYPE_USHORT4: return "ushort4";
- case IMAGE_DATA_TYPE_USHORT: return "ushort";
- case IMAGE_DATA_NUM_TYPES:
- assert(!"System enumerator type, should never be used");
- return "";
- }
- assert(!"Unhandled image data type");
- return "";
+ switch (type) {
+ case IMAGE_DATA_TYPE_FLOAT4:
+ return "float4";
+ case IMAGE_DATA_TYPE_BYTE4:
+ return "byte4";
+ case IMAGE_DATA_TYPE_HALF4:
+ return "half4";
+ case IMAGE_DATA_TYPE_FLOAT:
+ return "float";
+ case IMAGE_DATA_TYPE_BYTE:
+ return "byte";
+ case IMAGE_DATA_TYPE_HALF:
+ return "half";
+ case IMAGE_DATA_TYPE_USHORT4:
+ return "ushort4";
+ case IMAGE_DATA_TYPE_USHORT:
+ return "ushort";
+ case IMAGE_DATA_NUM_TYPES:
+ assert(!"System enumerator type, should never be used");
+ return "";
+ }
+ assert(!"Unhandled image data type");
+ return "";
}
} // namespace
-ImageManager::ImageManager(const DeviceInfo& info)
+ImageManager::ImageManager(const DeviceInfo &info)
{
- need_update = true;
- osl_texture_system = NULL;
- animation_frame = 0;
+ need_update = true;
+ osl_texture_system = NULL;
+ animation_frame = 0;
- /* Set image limits */
- max_num_images = TEX_NUM_MAX;
- has_half_images = info.has_half_images;
+ /* Set image limits */
+ max_num_images = TEX_NUM_MAX;
+ has_half_images = info.has_half_images;
- for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- tex_num_images[type] = 0;
- }
+ for (size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ tex_num_images[type] = 0;
+ }
}
ImageManager::~ImageManager()
{
- for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++)
- assert(!images[type][slot]);
- }
+ for (size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++)
+ assert(!images[type][slot]);
+ }
}
void ImageManager::set_osl_texture_system(void *texture_system)
{
- osl_texture_system = texture_system;
+ osl_texture_system = texture_system;
}
bool ImageManager::set_animation_frame_update(int frame)
{
- if(frame != animation_frame) {
- animation_frame = frame;
-
- for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- if(images[type][slot] && images[type][slot]->animated)
- return true;
- }
- }
- }
-
- return false;
+ if (frame != animation_frame) {
+ animation_frame = frame;
+
+ for (size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++) {
+ if (images[type][slot] && images[type][slot]->animated)
+ return true;
+ }
+ }
+ }
+
+ return false;
}
device_memory *ImageManager::image_memory(int flat_slot)
{
- ImageDataType type;
- int slot = flattened_slot_to_type_index(flat_slot, &type);
+ ImageDataType type;
+ int slot = flattened_slot_to_type_index(flat_slot, &type);
- Image *img = images[type][slot];
+ Image *img = images[type][slot];
- return img->mem;
+ return img->mem;
}
-bool ImageManager::get_image_metadata(int flat_slot,
- ImageMetaData& metadata)
+bool ImageManager::get_image_metadata(int flat_slot, ImageMetaData &metadata)
{
- if(flat_slot == -1) {
- return false;
- }
+ if (flat_slot == -1) {
+ return false;
+ }
- ImageDataType type;
- int slot = flattened_slot_to_type_index(flat_slot, &type);
+ ImageDataType type;
+ int slot = flattened_slot_to_type_index(flat_slot, &type);
- Image *img = images[type][slot];
- if(img) {
- metadata = img->metadata;
- return true;
- }
+ Image *img = images[type][slot];
+ if (img) {
+ metadata = img->metadata;
+ return true;
+ }
- return false;
+ return false;
}
-bool ImageManager::get_image_metadata(const string& filename,
+bool ImageManager::get_image_metadata(const string &filename,
void *builtin_data,
- ImageMetaData& metadata)
+ ImageMetaData &metadata)
{
- memset(&metadata, 0, sizeof(metadata));
-
- if(builtin_data) {
- if(builtin_image_info_cb) {
- builtin_image_info_cb(filename, builtin_data, metadata);
- }
- else {
- return false;
- }
-
- if(metadata.is_float) {
- metadata.is_linear = true;
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4
- : IMAGE_DATA_TYPE_FLOAT;
- }
- else {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4
- : IMAGE_DATA_TYPE_BYTE;
- }
-
- return true;
- }
-
- /* Perform preliminary checks, with meaningful logging. */
- if(!path_exists(filename)) {
- VLOG(1) << "File '" << filename << "' does not exist.";
- return false;
- }
- if(path_is_directory(filename)) {
- VLOG(1) << "File '" << filename
- << "' is a directory, can't use as image.";
- return false;
- }
-
- unique_ptr<ImageInput> in(ImageInput::create(filename));
-
- if(!in) {
- return false;
- }
-
- ImageSpec spec;
- if(!in->open(filename, spec)) {
- return false;
- }
-
- metadata.width = spec.width;
- metadata.height = spec.height;
- metadata.depth = spec.depth;
-
-
- /* Check the main format, and channel formats. */
- size_t channel_size = spec.format.basesize();
-
- if(spec.format.is_floating_point()) {
- metadata.is_float = true;
- metadata.is_linear = true;
- }
-
- for(size_t channel = 0; channel < spec.channelformats.size(); channel++) {
- channel_size = max(channel_size, spec.channelformats[channel].basesize());
- if(spec.channelformats[channel].is_floating_point()) {
- metadata.is_float = true;
- metadata.is_linear = true;
- }
- }
-
- /* check if it's half float */
- if(spec.format == TypeDesc::HALF) {
- metadata.is_half = true;
- }
-
- /* basic color space detection, not great but better than nothing
- * before we do OpenColorIO integration */
- if(metadata.is_float) {
- string colorspace = spec.get_string_attribute("oiio:ColorSpace");
-
- metadata.is_linear = !(colorspace == "sRGB" ||
- colorspace == "GammaCorrected" ||
- (colorspace == "" &&
- (strcmp(in->format_name(), "png") == 0 ||
- strcmp(in->format_name(), "tiff") == 0 ||
- strcmp(in->format_name(), "dpx") == 0 ||
- strcmp(in->format_name(), "jpeg2000") == 0)));
- }
- else {
- metadata.is_linear = false;
- }
-
- /* set type and channels */
- metadata.channels = spec.nchannels;
-
- if(metadata.is_half) {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4
- : IMAGE_DATA_TYPE_HALF;
- }
- else if(metadata.is_float) {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4
- : IMAGE_DATA_TYPE_FLOAT;
- }
- else if(spec.format == TypeDesc::USHORT) {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4
- : IMAGE_DATA_TYPE_USHORT;
- }
- else {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4
- : IMAGE_DATA_TYPE_BYTE;
- }
-
- in->close();
-
- return true;
+ memset(&metadata, 0, sizeof(metadata));
+
+ if (builtin_data) {
+ if (builtin_image_info_cb) {
+ builtin_image_info_cb(filename, builtin_data, metadata);
+ }
+ else {
+ return false;
+ }
+
+ if (metadata.is_float) {
+ metadata.is_linear = true;
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
+ }
+ else {
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
+ }
+
+ return true;
+ }
+
+ /* Perform preliminary checks, with meaningful logging. */
+ if (!path_exists(filename)) {
+ VLOG(1) << "File '" << filename << "' does not exist.";
+ return false;
+ }
+ if (path_is_directory(filename)) {
+ VLOG(1) << "File '" << filename << "' is a directory, can't use as image.";
+ return false;
+ }
+
+ unique_ptr<ImageInput> in(ImageInput::create(filename));
+
+ if (!in) {
+ return false;
+ }
+
+ ImageSpec spec;
+ if (!in->open(filename, spec)) {
+ return false;
+ }
+
+ metadata.width = spec.width;
+ metadata.height = spec.height;
+ metadata.depth = spec.depth;
+
+ /* Check the main format, and channel formats. */
+ size_t channel_size = spec.format.basesize();
+
+ if (spec.format.is_floating_point()) {
+ metadata.is_float = true;
+ metadata.is_linear = true;
+ }
+
+ for (size_t channel = 0; channel < spec.channelformats.size(); channel++) {
+ channel_size = max(channel_size, spec.channelformats[channel].basesize());
+ if (spec.channelformats[channel].is_floating_point()) {
+ metadata.is_float = true;
+ metadata.is_linear = true;
+ }
+ }
+
+ /* check if it's half float */
+ if (spec.format == TypeDesc::HALF) {
+ metadata.is_half = true;
+ }
+
+ /* basic color space detection, not great but better than nothing
+ * before we do OpenColorIO integration */
+ if (metadata.is_float) {
+ string colorspace = spec.get_string_attribute("oiio:ColorSpace");
+
+ metadata.is_linear = !(
+ colorspace == "sRGB" || colorspace == "GammaCorrected" ||
+ (colorspace == "" &&
+ (strcmp(in->format_name(), "png") == 0 || strcmp(in->format_name(), "tiff") == 0 ||
+ strcmp(in->format_name(), "dpx") == 0 || strcmp(in->format_name(), "jpeg2000") == 0)));
+ }
+ else {
+ metadata.is_linear = false;
+ }
+
+ /* set type and channels */
+ metadata.channels = spec.nchannels;
+
+ if (metadata.is_half) {
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4 : IMAGE_DATA_TYPE_HALF;
+ }
+ else if (metadata.is_float) {
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
+ }
+ else if (spec.format == TypeDesc::USHORT) {
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4 : IMAGE_DATA_TYPE_USHORT;
+ }
+ else {
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
+ }
+
+ in->close();
+
+ return true;
}
static bool image_equals(ImageManager::Image *image,
- const string& filename,
+ const string &filename,
void *builtin_data,
InterpolationType interpolation,
ExtensionType extension,
bool use_alpha)
{
- return image->filename == filename &&
- image->builtin_data == builtin_data &&
- image->interpolation == interpolation &&
- image->extension == extension &&
- image->use_alpha == use_alpha;
+ return image->filename == filename && image->builtin_data == builtin_data &&
+ image->interpolation == interpolation && image->extension == extension &&
+ image->use_alpha == use_alpha;
}
-int ImageManager::add_image(const string& filename,
+int ImageManager::add_image(const string &filename,
void *builtin_data,
bool animated,
float frame,
InterpolationType interpolation,
ExtensionType extension,
bool use_alpha,
- ImageMetaData& metadata)
+ ImageMetaData &metadata)
{
- Image *img;
- size_t slot;
-
- get_image_metadata(filename, builtin_data, metadata);
- ImageDataType type = metadata.type;
-
- thread_scoped_lock device_lock(device_mutex);
-
- /* No half textures on OpenCL, use full float instead. */
- if(!has_half_images) {
- if(type == IMAGE_DATA_TYPE_HALF4) {
- type = IMAGE_DATA_TYPE_FLOAT4;
- }
- else if(type == IMAGE_DATA_TYPE_HALF) {
- type = IMAGE_DATA_TYPE_FLOAT;
- }
- }
-
- /* Fnd existing image. */
- for(slot = 0; slot < images[type].size(); slot++) {
- img = images[type][slot];
- if(img && image_equals(img,
- filename,
- builtin_data,
- interpolation,
- extension,
- use_alpha))
- {
- if(img->frame != frame) {
- img->frame = frame;
- img->need_load = true;
- }
- if(img->use_alpha != use_alpha) {
- img->use_alpha = use_alpha;
- img->need_load = true;
- }
- if(!(img->metadata == metadata)) {
- img->metadata = metadata;
- img->need_load = true;
- }
- img->users++;
- return type_index_to_flattened_slot(slot, type);
- }
- }
-
- /* Find free slot. */
- for(slot = 0; slot < images[type].size(); slot++) {
- if(!images[type][slot])
- break;
- }
-
- /* Count if we're over the limit.
- * Very unlikely, since max_num_images is insanely big. But better safe
- * than sorry.
- */
- int tex_count = 0;
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- tex_count += tex_num_images[type];
- }
- if(tex_count > max_num_images) {
- printf("ImageManager::add_image: Reached image limit (%d), "
- "skipping '%s'\n", max_num_images, filename.c_str());
- return -1;
- }
-
- if(slot == images[type].size()) {
- images[type].resize(images[type].size() + 1);
- }
-
- /* Add new image. */
- img = new Image();
- img->filename = filename;
- img->builtin_data = builtin_data;
- img->metadata = metadata;
- img->need_load = true;
- img->animated = animated;
- img->frame = frame;
- img->interpolation = interpolation;
- img->extension = extension;
- img->users = 1;
- img->use_alpha = use_alpha;
- img->mem = NULL;
-
- images[type][slot] = img;
-
- ++tex_num_images[type];
-
- need_update = true;
-
- return type_index_to_flattened_slot(slot, type);
+ Image *img;
+ size_t slot;
+
+ get_image_metadata(filename, builtin_data, metadata);
+ ImageDataType type = metadata.type;
+
+ thread_scoped_lock device_lock(device_mutex);
+
+ /* No half textures on OpenCL, use full float instead. */
+ if (!has_half_images) {
+ if (type == IMAGE_DATA_TYPE_HALF4) {
+ type = IMAGE_DATA_TYPE_FLOAT4;
+ }
+ else if (type == IMAGE_DATA_TYPE_HALF) {
+ type = IMAGE_DATA_TYPE_FLOAT;
+ }
+ }
+
+ /* Fnd existing image. */
+ for (slot = 0; slot < images[type].size(); slot++) {
+ img = images[type][slot];
+ if (img && image_equals(img, filename, builtin_data, interpolation, extension, use_alpha)) {
+ if (img->frame != frame) {
+ img->frame = frame;
+ img->need_load = true;
+ }
+ if (img->use_alpha != use_alpha) {
+ img->use_alpha = use_alpha;
+ img->need_load = true;
+ }
+ if (!(img->metadata == metadata)) {
+ img->metadata = metadata;
+ img->need_load = true;
+ }
+ img->users++;
+ return type_index_to_flattened_slot(slot, type);
+ }
+ }
+
+ /* Find free slot. */
+ for (slot = 0; slot < images[type].size(); slot++) {
+ if (!images[type][slot])
+ break;
+ }
+
+ /* Count if we're over the limit.
+ * Very unlikely, since max_num_images is insanely big. But better safe
+ * than sorry.
+ */
+ int tex_count = 0;
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ tex_count += tex_num_images[type];
+ }
+ if (tex_count > max_num_images) {
+ printf(
+ "ImageManager::add_image: Reached image limit (%d), "
+ "skipping '%s'\n",
+ max_num_images,
+ filename.c_str());
+ return -1;
+ }
+
+ if (slot == images[type].size()) {
+ images[type].resize(images[type].size() + 1);
+ }
+
+ /* Add new image. */
+ img = new Image();
+ img->filename = filename;
+ img->builtin_data = builtin_data;
+ img->metadata = metadata;
+ img->need_load = true;
+ img->animated = animated;
+ img->frame = frame;
+ img->interpolation = interpolation;
+ img->extension = extension;
+ img->users = 1;
+ img->use_alpha = use_alpha;
+ img->mem = NULL;
+
+ images[type][slot] = img;
+
+ ++tex_num_images[type];
+
+ need_update = true;
+
+ return type_index_to_flattened_slot(slot, type);
}
void ImageManager::remove_image(int flat_slot)
{
- ImageDataType type;
- int slot = flattened_slot_to_type_index(flat_slot, &type);
+ ImageDataType type;
+ int slot = flattened_slot_to_type_index(flat_slot, &type);
- Image *image = images[type][slot];
- assert(image && image->users >= 1);
+ Image *image = images[type][slot];
+ assert(image && image->users >= 1);
- /* decrement user count */
- image->users--;
+ /* decrement user count */
+ image->users--;
- /* don't remove immediately, rather do it all together later on. one of
- * the reasons for this is that on shader changes we add and remove nodes
- * that use them, but we do not want to reload the image all the time. */
- if(image->users == 0)
- need_update = true;
+ /* don't remove immediately, rather do it all together later on. one of
+ * the reasons for this is that on shader changes we add and remove nodes
+ * that use them, but we do not want to reload the image all the time. */
+ if (image->users == 0)
+ need_update = true;
}
-void ImageManager::remove_image(const string& filename,
+void ImageManager::remove_image(const string &filename,
void *builtin_data,
InterpolationType interpolation,
ExtensionType extension,
bool use_alpha)
{
- size_t slot;
-
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(slot = 0; slot < images[type].size(); slot++) {
- if(images[type][slot] && image_equals(images[type][slot],
- filename,
- builtin_data,
- interpolation,
- extension,
- use_alpha))
- {
- remove_image(type_index_to_flattened_slot(slot, (ImageDataType)type));
- return;
- }
- }
- }
+ size_t slot;
+
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (slot = 0; slot < images[type].size(); slot++) {
+ if (images[type][slot] &&
+ image_equals(
+ images[type][slot], filename, builtin_data, interpolation, extension, use_alpha)) {
+ remove_image(type_index_to_flattened_slot(slot, (ImageDataType)type));
+ return;
+ }
+ }
+ }
}
/* TODO(sergey): Deduplicate with the iteration above, but make it pretty,
* without bunch of arguments passing around making code readability even
* more cluttered.
*/
-void ImageManager::tag_reload_image(const string& filename,
+void ImageManager::tag_reload_image(const string &filename,
void *builtin_data,
InterpolationType interpolation,
ExtensionType extension,
bool use_alpha)
{
- for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- if(images[type][slot] && image_equals(images[type][slot],
- filename,
- builtin_data,
- interpolation,
- extension,
- use_alpha))
- {
- images[type][slot]->need_load = true;
- break;
- }
- }
- }
+ for (size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++) {
+ if (images[type][slot] &&
+ image_equals(
+ images[type][slot], filename, builtin_data, interpolation, extension, use_alpha)) {
+ images[type][slot]->need_load = true;
+ break;
+ }
+ }
+ }
}
-bool ImageManager::file_load_image_generic(Image *img,
- unique_ptr<ImageInput> *in)
+bool ImageManager::file_load_image_generic(Image *img, unique_ptr<ImageInput> *in)
{
- if(img->filename == "")
- return false;
-
- if(!img->builtin_data) {
- /* NOTE: Error logging is done in meta data acquisition. */
- if(!path_exists(img->filename) || path_is_directory(img->filename)) {
- return false;
- }
-
- /* load image from file through OIIO */
- *in = unique_ptr<ImageInput>(ImageInput::create(img->filename));
-
- if(!*in)
- return false;
-
- ImageSpec spec = ImageSpec();
- ImageSpec config = ImageSpec();
-
- if(img->use_alpha == false)
- config.attribute("oiio:UnassociatedAlpha", 1);
-
- if(!(*in)->open(img->filename, spec, config)) {
- return false;
- }
- }
- else {
- /* load image using builtin images callbacks */
- if(!builtin_image_info_cb || !builtin_image_pixels_cb)
- return false;
- }
-
- /* we only handle certain number of components */
- if(!(img->metadata.channels >= 1 && img->metadata.channels <= 4)) {
- if(*in) {
- (*in)->close();
- }
- return false;
- }
-
- return true;
+ if (img->filename == "")
+ return false;
+
+ if (!img->builtin_data) {
+ /* NOTE: Error logging is done in meta data acquisition. */
+ if (!path_exists(img->filename) || path_is_directory(img->filename)) {
+ return false;
+ }
+
+ /* load image from file through OIIO */
+ *in = unique_ptr<ImageInput>(ImageInput::create(img->filename));
+
+ if (!*in)
+ return false;
+
+ ImageSpec spec = ImageSpec();
+ ImageSpec config = ImageSpec();
+
+ if (img->use_alpha == false)
+ config.attribute("oiio:UnassociatedAlpha", 1);
+
+ if (!(*in)->open(img->filename, spec, config)) {
+ return false;
+ }
+ }
+ else {
+ /* load image using builtin images callbacks */
+ if (!builtin_image_info_cb || !builtin_image_pixels_cb)
+ return false;
+ }
+
+ /* we only handle certain number of components */
+ if (!(img->metadata.channels >= 1 && img->metadata.channels <= 4)) {
+ if (*in) {
+ (*in)->close();
+ }
+ return false;
+ }
+
+ return true;
}
-template<TypeDesc::BASETYPE FileFormat,
- typename StorageType,
- typename DeviceType>
+template<TypeDesc::BASETYPE FileFormat, typename StorageType, typename DeviceType>
bool ImageManager::file_load_image(Image *img,
ImageDataType type,
int texture_limit,
- device_vector<DeviceType>& tex_img)
+ device_vector<DeviceType> &tex_img)
{
- unique_ptr<ImageInput> in = NULL;
- if(!file_load_image_generic(img, &in)) {
- return false;
- }
-
- /* Get metadata. */
- int width = img->metadata.width;
- int height = img->metadata.height;
- int depth = img->metadata.depth;
- int components = img->metadata.channels;
-
- /* Read RGBA pixels. */
- vector<StorageType> pixels_storage;
- StorageType *pixels;
- const size_t max_size = max(max(width, height), depth);
- if(max_size == 0) {
- /* Don't bother with invalid images. */
- return false;
- }
- if(texture_limit > 0 && max_size > texture_limit) {
- pixels_storage.resize(((size_t)width)*height*depth*4);
- pixels = &pixels_storage[0];
- }
- else {
- thread_scoped_lock device_lock(device_mutex);
- pixels = (StorageType*)tex_img.alloc(width, height, depth);
- }
- if(pixels == NULL) {
- /* Could be that we've run out of memory. */
- return false;
- }
- bool cmyk = false;
- const size_t num_pixels = ((size_t)width) * height * depth;
- if(in) {
- StorageType *readpixels = pixels;
- vector<StorageType> tmppixels;
- if(components > 4) {
- tmppixels.resize(((size_t)width)*height*components);
- readpixels = &tmppixels[0];
- }
- if(depth <= 1) {
- size_t scanlinesize = ((size_t)width)*components*sizeof(StorageType);
- in->read_image(FileFormat,
- (uchar*)readpixels + (height-1)*scanlinesize,
- AutoStride,
- -scanlinesize,
- AutoStride);
- }
- else {
- in->read_image(FileFormat, (uchar*)readpixels);
- }
- if(components > 4) {
- size_t dimensions = ((size_t)width)*height;
- for(size_t i = dimensions-1, pixel = 0; pixel < dimensions; pixel++, i--) {
- pixels[i*4+3] = tmppixels[i*components+3];
- pixels[i*4+2] = tmppixels[i*components+2];
- pixels[i*4+1] = tmppixels[i*components+1];
- pixels[i*4+0] = tmppixels[i*components+0];
- }
- tmppixels.clear();
- }
- cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4;
- in->close();
- }
- else {
- if(FileFormat == TypeDesc::FLOAT) {
- builtin_image_float_pixels_cb(img->filename,
- img->builtin_data,
- (float*)&pixels[0],
- num_pixels * components,
- img->metadata.builtin_free_cache);
- }
- else if(FileFormat == TypeDesc::UINT8) {
- builtin_image_pixels_cb(img->filename,
- img->builtin_data,
- (uchar*)&pixels[0],
- num_pixels * components,
- img->metadata.builtin_free_cache);
- }
- else {
- /* TODO(dingto): Support half for ImBuf. */
- }
- }
- /* Check if we actually have a float4 slot, in case components == 1,
- * but device doesn't support single channel textures.
- */
- bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 ||
- type == IMAGE_DATA_TYPE_HALF4 ||
- type == IMAGE_DATA_TYPE_BYTE4 ||
- type == IMAGE_DATA_TYPE_USHORT4);
- if(is_rgba) {
- const StorageType one = util_image_cast_from_float<StorageType>(1.0f);
-
- if(cmyk) {
- /* CMYK */
- for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
- float c = util_image_cast_to_float(pixels[i*4+0]);
- float m = util_image_cast_to_float(pixels[i*4+1]);
- float y = util_image_cast_to_float(pixels[i*4+2]);
- float k = util_image_cast_to_float(pixels[i*4+3]);
- pixels[i*4+0] = util_image_cast_from_float<StorageType>((1.0f - c) * (1.0f - k));
- pixels[i*4+1] = util_image_cast_from_float<StorageType>((1.0f - m) * (1.0f - k));
- pixels[i*4+2] = util_image_cast_from_float<StorageType>((1.0f - y) * (1.0f - k));
- pixels[i*4+3] = one;
- }
- }
- else if(components == 2) {
- /* grayscale + alpha */
- for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
- pixels[i*4+3] = pixels[i*2+1];
- pixels[i*4+2] = pixels[i*2+0];
- pixels[i*4+1] = pixels[i*2+0];
- pixels[i*4+0] = pixels[i*2+0];
- }
- }
- else if(components == 3) {
- /* RGB */
- for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
- pixels[i*4+3] = one;
- pixels[i*4+2] = pixels[i*3+2];
- pixels[i*4+1] = pixels[i*3+1];
- pixels[i*4+0] = pixels[i*3+0];
- }
- }
- else if(components == 1) {
- /* grayscale */
- for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
- pixels[i*4+3] = one;
- pixels[i*4+2] = pixels[i];
- pixels[i*4+1] = pixels[i];
- pixels[i*4+0] = pixels[i];
- }
- }
- if(img->use_alpha == false) {
- for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
- pixels[i*4+3] = one;
- }
- }
- }
- /* Make sure we don't have buggy values. */
- if(FileFormat == TypeDesc::FLOAT) {
- /* For RGBA buffers we put all channels to 0 if either of them is not
- * finite. This way we avoid possible artifacts caused by fully changed
- * hue.
- */
- if(is_rgba) {
- for(size_t i = 0; i < num_pixels; i += 4) {
- StorageType *pixel = &pixels[i*4];
- if(!isfinite(pixel[0]) ||
- !isfinite(pixel[1]) ||
- !isfinite(pixel[2]) ||
- !isfinite(pixel[3]))
- {
- pixel[0] = 0;
- pixel[1] = 0;
- pixel[2] = 0;
- pixel[3] = 0;
- }
- }
- }
- else {
- for(size_t i = 0; i < num_pixels; ++i) {
- StorageType *pixel = &pixels[i];
- if(!isfinite(pixel[0])) {
- pixel[0] = 0;
- }
- }
- }
- }
- /* Scale image down if needed. */
- if(pixels_storage.size() > 0) {
- float scale_factor = 1.0f;
- while(max_size * scale_factor > texture_limit) {
- scale_factor *= 0.5f;
- }
- VLOG(1) << "Scaling image " << img->filename
- << " by a factor of " << scale_factor << ".";
- vector<StorageType> scaled_pixels;
- size_t scaled_width, scaled_height, scaled_depth;
- util_image_resize_pixels(pixels_storage,
- width, height, depth,
- is_rgba ? 4 : 1,
- scale_factor,
- &scaled_pixels,
- &scaled_width, &scaled_height, &scaled_depth);
-
- StorageType *texture_pixels;
-
- {
- thread_scoped_lock device_lock(device_mutex);
- texture_pixels = (StorageType*)tex_img.alloc(scaled_width,
- scaled_height,
- scaled_depth);
- }
-
- memcpy(texture_pixels,
- &scaled_pixels[0],
- scaled_pixels.size() * sizeof(StorageType));
- }
- return true;
+ unique_ptr<ImageInput> in = NULL;
+ if (!file_load_image_generic(img, &in)) {
+ return false;
+ }
+
+ /* Get metadata. */
+ int width = img->metadata.width;
+ int height = img->metadata.height;
+ int depth = img->metadata.depth;
+ int components = img->metadata.channels;
+
+ /* Read RGBA pixels. */
+ vector<StorageType> pixels_storage;
+ StorageType *pixels;
+ const size_t max_size = max(max(width, height), depth);
+ if (max_size == 0) {
+ /* Don't bother with invalid images. */
+ return false;
+ }
+ if (texture_limit > 0 && max_size > texture_limit) {
+ pixels_storage.resize(((size_t)width) * height * depth * 4);
+ pixels = &pixels_storage[0];
+ }
+ else {
+ thread_scoped_lock device_lock(device_mutex);
+ pixels = (StorageType *)tex_img.alloc(width, height, depth);
+ }
+ if (pixels == NULL) {
+ /* Could be that we've run out of memory. */
+ return false;
+ }
+ bool cmyk = false;
+ const size_t num_pixels = ((size_t)width) * height * depth;
+ if (in) {
+ StorageType *readpixels = pixels;
+ vector<StorageType> tmppixels;
+ if (components > 4) {
+ tmppixels.resize(((size_t)width) * height * components);
+ readpixels = &tmppixels[0];
+ }
+ if (depth <= 1) {
+ size_t scanlinesize = ((size_t)width) * components * sizeof(StorageType);
+ in->read_image(FileFormat,
+ (uchar *)readpixels + (height - 1) * scanlinesize,
+ AutoStride,
+ -scanlinesize,
+ AutoStride);
+ }
+ else {
+ in->read_image(FileFormat, (uchar *)readpixels);
+ }
+ if (components > 4) {
+ size_t dimensions = ((size_t)width) * height;
+ for (size_t i = dimensions - 1, pixel = 0; pixel < dimensions; pixel++, i--) {
+ pixels[i * 4 + 3] = tmppixels[i * components + 3];
+ pixels[i * 4 + 2] = tmppixels[i * components + 2];
+ pixels[i * 4 + 1] = tmppixels[i * components + 1];
+ pixels[i * 4 + 0] = tmppixels[i * components + 0];
+ }
+ tmppixels.clear();
+ }
+ cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4;
+ in->close();
+ }
+ else {
+ if (FileFormat == TypeDesc::FLOAT) {
+ builtin_image_float_pixels_cb(img->filename,
+ img->builtin_data,
+ (float *)&pixels[0],
+ num_pixels * components,
+ img->metadata.builtin_free_cache);
+ }
+ else if (FileFormat == TypeDesc::UINT8) {
+ builtin_image_pixels_cb(img->filename,
+ img->builtin_data,
+ (uchar *)&pixels[0],
+ num_pixels * components,
+ img->metadata.builtin_free_cache);
+ }
+ else {
+ /* TODO(dingto): Support half for ImBuf. */
+ }
+ }
+ /* Check if we actually have a float4 slot, in case components == 1,
+ * but device doesn't support single channel textures.
+ */
+ bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 || type == IMAGE_DATA_TYPE_HALF4 ||
+ type == IMAGE_DATA_TYPE_BYTE4 || type == IMAGE_DATA_TYPE_USHORT4);
+ if (is_rgba) {
+ const StorageType one = util_image_cast_from_float<StorageType>(1.0f);
+
+ if (cmyk) {
+ /* CMYK */
+ for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+ float c = util_image_cast_to_float(pixels[i * 4 + 0]);
+ float m = util_image_cast_to_float(pixels[i * 4 + 1]);
+ float y = util_image_cast_to_float(pixels[i * 4 + 2]);
+ float k = util_image_cast_to_float(pixels[i * 4 + 3]);
+ pixels[i * 4 + 0] = util_image_cast_from_float<StorageType>((1.0f - c) * (1.0f - k));
+ pixels[i * 4 + 1] = util_image_cast_from_float<StorageType>((1.0f - m) * (1.0f - k));
+ pixels[i * 4 + 2] = util_image_cast_from_float<StorageType>((1.0f - y) * (1.0f - k));
+ pixels[i * 4 + 3] = one;
+ }
+ }
+ else if (components == 2) {
+ /* grayscale + alpha */
+ for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+ pixels[i * 4 + 3] = pixels[i * 2 + 1];
+ pixels[i * 4 + 2] = pixels[i * 2 + 0];
+ pixels[i * 4 + 1] = pixels[i * 2 + 0];
+ pixels[i * 4 + 0] = pixels[i * 2 + 0];
+ }
+ }
+ else if (components == 3) {
+ /* RGB */
+ for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+ pixels[i * 4 + 3] = one;
+ pixels[i * 4 + 2] = pixels[i * 3 + 2];
+ pixels[i * 4 + 1] = pixels[i * 3 + 1];
+ pixels[i * 4 + 0] = pixels[i * 3 + 0];
+ }
+ }
+ else if (components == 1) {
+ /* grayscale */
+ for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+ pixels[i * 4 + 3] = one;
+ pixels[i * 4 + 2] = pixels[i];
+ pixels[i * 4 + 1] = pixels[i];
+ pixels[i * 4 + 0] = pixels[i];
+ }
+ }
+ if (img->use_alpha == false) {
+ for (size_t i = num_pixels - 1, pixel = 0; pixel < num_pixels; pixel++, i--) {
+ pixels[i * 4 + 3] = one;
+ }
+ }
+ }
+ /* Make sure we don't have buggy values. */
+ if (FileFormat == TypeDesc::FLOAT) {
+ /* For RGBA buffers we put all channels to 0 if either of them is not
+ * finite. This way we avoid possible artifacts caused by fully changed
+ * hue.
+ */
+ if (is_rgba) {
+ for (size_t i = 0; i < num_pixels; i += 4) {
+ StorageType *pixel = &pixels[i * 4];
+ if (!isfinite(pixel[0]) || !isfinite(pixel[1]) || !isfinite(pixel[2]) ||
+ !isfinite(pixel[3])) {
+ pixel[0] = 0;
+ pixel[1] = 0;
+ pixel[2] = 0;
+ pixel[3] = 0;
+ }
+ }
+ }
+ else {
+ for (size_t i = 0; i < num_pixels; ++i) {
+ StorageType *pixel = &pixels[i];
+ if (!isfinite(pixel[0])) {
+ pixel[0] = 0;
+ }
+ }
+ }
+ }
+ /* Scale image down if needed. */
+ if (pixels_storage.size() > 0) {
+ float scale_factor = 1.0f;
+ while (max_size * scale_factor > texture_limit) {
+ scale_factor *= 0.5f;
+ }
+ VLOG(1) << "Scaling image " << img->filename << " by a factor of " << scale_factor << ".";
+ vector<StorageType> scaled_pixels;
+ size_t scaled_width, scaled_height, scaled_depth;
+ util_image_resize_pixels(pixels_storage,
+ width,
+ height,
+ depth,
+ is_rgba ? 4 : 1,
+ scale_factor,
+ &scaled_pixels,
+ &scaled_width,
+ &scaled_height,
+ &scaled_depth);
+
+ StorageType *texture_pixels;
+
+ {
+ thread_scoped_lock device_lock(device_mutex);
+ texture_pixels = (StorageType *)tex_img.alloc(scaled_width, scaled_height, scaled_depth);
+ }
+
+ memcpy(texture_pixels, &scaled_pixels[0], scaled_pixels.size() * sizeof(StorageType));
+ }
+ return true;
}
-void ImageManager::device_load_image(Device *device,
- Scene *scene,
- ImageDataType type,
- int slot,
- Progress *progress)
+void ImageManager::device_load_image(
+ Device *device, Scene *scene, ImageDataType type, int slot, Progress *progress)
{
- if(progress->get_cancel())
- return;
-
- Image *img = images[type][slot];
-
- if(osl_texture_system && !img->builtin_data)
- return;
-
- string filename = path_filename(images[type][slot]->filename);
- progress->set_status("Updating Images", "Loading " + filename);
-
- const int texture_limit = scene->params.texture_limit;
-
- /* Slot assignment */
- int flat_slot = type_index_to_flattened_slot(slot, type);
- img->mem_name = string_printf("__tex_image_%s_%03d",
- name_from_type(type), flat_slot);
-
- /* Free previous texture in slot. */
- if(img->mem) {
- thread_scoped_lock device_lock(device_mutex);
- delete img->mem;
- img->mem = NULL;
- }
-
- /* Create new texture. */
- if(type == IMAGE_DATA_TYPE_FLOAT4) {
- device_vector<float4> *tex_img
- = new device_vector<float4>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::FLOAT, float>(img,
- type,
- texture_limit,
- *tex_img))
- {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- float *pixels = (float*)tex_img->alloc(1, 1);
-
- pixels[0] = TEX_IMAGE_MISSING_R;
- pixels[1] = TEX_IMAGE_MISSING_G;
- pixels[2] = TEX_IMAGE_MISSING_B;
- pixels[3] = TEX_IMAGE_MISSING_A;
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_FLOAT) {
- device_vector<float> *tex_img
- = new device_vector<float>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::FLOAT, float>(img,
- type,
- texture_limit,
- *tex_img))
- {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- float *pixels = (float*)tex_img->alloc(1, 1);
-
- pixels[0] = TEX_IMAGE_MISSING_R;
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_BYTE4) {
- device_vector<uchar4> *tex_img
- = new device_vector<uchar4>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::UINT8, uchar>(img,
- type,
- texture_limit,
- *tex_img))
- {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- uchar *pixels = (uchar*)tex_img->alloc(1, 1);
-
- pixels[0] = (TEX_IMAGE_MISSING_R * 255);
- pixels[1] = (TEX_IMAGE_MISSING_G * 255);
- pixels[2] = (TEX_IMAGE_MISSING_B * 255);
- pixels[3] = (TEX_IMAGE_MISSING_A * 255);
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_BYTE) {
- device_vector<uchar> *tex_img
- = new device_vector<uchar>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::UINT8, uchar>(img,
- type,
- texture_limit,
- *tex_img)) {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- uchar *pixels = (uchar*)tex_img->alloc(1, 1);
-
- pixels[0] = (TEX_IMAGE_MISSING_R * 255);
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_HALF4) {
- device_vector<half4> *tex_img
- = new device_vector<half4>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::HALF, half>(img,
- type,
- texture_limit,
- *tex_img)) {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- half *pixels = (half*)tex_img->alloc(1, 1);
-
- pixels[0] = TEX_IMAGE_MISSING_R;
- pixels[1] = TEX_IMAGE_MISSING_G;
- pixels[2] = TEX_IMAGE_MISSING_B;
- pixels[3] = TEX_IMAGE_MISSING_A;
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_USHORT) {
- device_vector<uint16_t> *tex_img
- = new device_vector<uint16_t>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::USHORT, uint16_t>(img,
- type,
- texture_limit,
- *tex_img)) {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1);
-
- pixels[0] = (TEX_IMAGE_MISSING_R * 65535);
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_USHORT4) {
- device_vector<ushort4> *tex_img
- = new device_vector<ushort4>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::USHORT, uint16_t>(img,
- type,
- texture_limit,
- *tex_img)) {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1);
-
- pixels[0] = (TEX_IMAGE_MISSING_R * 65535);
- pixels[1] = (TEX_IMAGE_MISSING_G * 65535);
- pixels[2] = (TEX_IMAGE_MISSING_B * 65535);
- pixels[3] = (TEX_IMAGE_MISSING_A * 65535);
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- else if(type == IMAGE_DATA_TYPE_HALF) {
- device_vector<half> *tex_img
- = new device_vector<half>(device, img->mem_name.c_str(), MEM_TEXTURE);
-
- if(!file_load_image<TypeDesc::HALF, half>(img,
- type,
- texture_limit,
- *tex_img)) {
- /* on failure to load, we set a 1x1 pixels pink image */
- thread_scoped_lock device_lock(device_mutex);
- half *pixels = (half*)tex_img->alloc(1, 1);
-
- pixels[0] = TEX_IMAGE_MISSING_R;
- }
-
- img->mem = tex_img;
- img->mem->interpolation = img->interpolation;
- img->mem->extension = img->extension;
-
- thread_scoped_lock device_lock(device_mutex);
- tex_img->copy_to_device();
- }
- img->need_load = false;
+ if (progress->get_cancel())
+ return;
+
+ Image *img = images[type][slot];
+
+ if (osl_texture_system && !img->builtin_data)
+ return;
+
+ string filename = path_filename(images[type][slot]->filename);
+ progress->set_status("Updating Images", "Loading " + filename);
+
+ const int texture_limit = scene->params.texture_limit;
+
+ /* Slot assignment */
+ int flat_slot = type_index_to_flattened_slot(slot, type);
+ img->mem_name = string_printf("__tex_image_%s_%03d", name_from_type(type), flat_slot);
+
+ /* Free previous texture in slot. */
+ if (img->mem) {
+ thread_scoped_lock device_lock(device_mutex);
+ delete img->mem;
+ img->mem = NULL;
+ }
+
+ /* Create new texture. */
+ if (type == IMAGE_DATA_TYPE_FLOAT4) {
+ device_vector<float4> *tex_img = new device_vector<float4>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::FLOAT, float>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ float *pixels = (float *)tex_img->alloc(1, 1);
+
+ pixels[0] = TEX_IMAGE_MISSING_R;
+ pixels[1] = TEX_IMAGE_MISSING_G;
+ pixels[2] = TEX_IMAGE_MISSING_B;
+ pixels[3] = TEX_IMAGE_MISSING_A;
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_FLOAT) {
+ device_vector<float> *tex_img = new device_vector<float>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::FLOAT, float>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ float *pixels = (float *)tex_img->alloc(1, 1);
+
+ pixels[0] = TEX_IMAGE_MISSING_R;
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_BYTE4) {
+ device_vector<uchar4> *tex_img = new device_vector<uchar4>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::UINT8, uchar>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ uchar *pixels = (uchar *)tex_img->alloc(1, 1);
+
+ pixels[0] = (TEX_IMAGE_MISSING_R * 255);
+ pixels[1] = (TEX_IMAGE_MISSING_G * 255);
+ pixels[2] = (TEX_IMAGE_MISSING_B * 255);
+ pixels[3] = (TEX_IMAGE_MISSING_A * 255);
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_BYTE) {
+ device_vector<uchar> *tex_img = new device_vector<uchar>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::UINT8, uchar>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ uchar *pixels = (uchar *)tex_img->alloc(1, 1);
+
+ pixels[0] = (TEX_IMAGE_MISSING_R * 255);
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_HALF4) {
+ device_vector<half4> *tex_img = new device_vector<half4>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::HALF, half>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ half *pixels = (half *)tex_img->alloc(1, 1);
+
+ pixels[0] = TEX_IMAGE_MISSING_R;
+ pixels[1] = TEX_IMAGE_MISSING_G;
+ pixels[2] = TEX_IMAGE_MISSING_B;
+ pixels[3] = TEX_IMAGE_MISSING_A;
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_USHORT) {
+ device_vector<uint16_t> *tex_img = new device_vector<uint16_t>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::USHORT, uint16_t>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ uint16_t *pixels = (uint16_t *)tex_img->alloc(1, 1);
+
+ pixels[0] = (TEX_IMAGE_MISSING_R * 65535);
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_USHORT4) {
+ device_vector<ushort4> *tex_img = new device_vector<ushort4>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::USHORT, uint16_t>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ uint16_t *pixels = (uint16_t *)tex_img->alloc(1, 1);
+
+ pixels[0] = (TEX_IMAGE_MISSING_R * 65535);
+ pixels[1] = (TEX_IMAGE_MISSING_G * 65535);
+ pixels[2] = (TEX_IMAGE_MISSING_B * 65535);
+ pixels[3] = (TEX_IMAGE_MISSING_A * 65535);
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ else if (type == IMAGE_DATA_TYPE_HALF) {
+ device_vector<half> *tex_img = new device_vector<half>(
+ device, img->mem_name.c_str(), MEM_TEXTURE);
+
+ if (!file_load_image<TypeDesc::HALF, half>(img, type, texture_limit, *tex_img)) {
+ /* on failure to load, we set a 1x1 pixels pink image */
+ thread_scoped_lock device_lock(device_mutex);
+ half *pixels = (half *)tex_img->alloc(1, 1);
+
+ pixels[0] = TEX_IMAGE_MISSING_R;
+ }
+
+ img->mem = tex_img;
+ img->mem->interpolation = img->interpolation;
+ img->mem->extension = img->extension;
+
+ thread_scoped_lock device_lock(device_mutex);
+ tex_img->copy_to_device();
+ }
+ img->need_load = false;
}
void ImageManager::device_free_image(Device *, ImageDataType type, int slot)
{
- Image *img = images[type][slot];
+ Image *img = images[type][slot];
- if(img) {
- if(osl_texture_system && !img->builtin_data) {
+ if (img) {
+ if (osl_texture_system && !img->builtin_data) {
#ifdef WITH_OSL
- ustring filename(images[type][slot]->filename);
- ((OSL::TextureSystem*)osl_texture_system)->invalidate(filename);
+ ustring filename(images[type][slot]->filename);
+ ((OSL::TextureSystem *)osl_texture_system)->invalidate(filename);
#endif
- }
+ }
- if(img->mem) {
- thread_scoped_lock device_lock(device_mutex);
- delete img->mem;
- }
+ if (img->mem) {
+ thread_scoped_lock device_lock(device_mutex);
+ delete img->mem;
+ }
- delete img;
- images[type][slot] = NULL;
- --tex_num_images[type];
- }
+ delete img;
+ images[type][slot] = NULL;
+ --tex_num_images[type];
+ }
}
-void ImageManager::device_update(Device *device,
- Scene *scene,
- Progress& progress)
+void ImageManager::device_update(Device *device, Scene *scene, Progress &progress)
{
- if(!need_update) {
- return;
- }
-
- TaskPool pool;
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- if(!images[type][slot])
- continue;
-
- if(images[type][slot]->users == 0) {
- device_free_image(device, (ImageDataType)type, slot);
- }
- else if(images[type][slot]->need_load) {
- if(!osl_texture_system || images[type][slot]->builtin_data)
- pool.push(function_bind(&ImageManager::device_load_image,
- this,
- device,
- scene,
- (ImageDataType)type,
- slot,
- &progress));
- }
- }
- }
-
- pool.wait_work();
-
- need_update = false;
+ if (!need_update) {
+ return;
+ }
+
+ TaskPool pool;
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++) {
+ if (!images[type][slot])
+ continue;
+
+ if (images[type][slot]->users == 0) {
+ device_free_image(device, (ImageDataType)type, slot);
+ }
+ else if (images[type][slot]->need_load) {
+ if (!osl_texture_system || images[type][slot]->builtin_data)
+ pool.push(function_bind(&ImageManager::device_load_image,
+ this,
+ device,
+ scene,
+ (ImageDataType)type,
+ slot,
+ &progress));
+ }
+ }
+ }
+
+ pool.wait_work();
+
+ need_update = false;
}
void ImageManager::device_update_slot(Device *device,
@@ -1001,87 +943,80 @@ void ImageManager::device_update_slot(Device *device,
int flat_slot,
Progress *progress)
{
- ImageDataType type;
- int slot = flattened_slot_to_type_index(flat_slot, &type);
-
- Image *image = images[type][slot];
- assert(image != NULL);
-
- if(image->users == 0) {
- device_free_image(device, type, slot);
- }
- else if(image->need_load) {
- if(!osl_texture_system || image->builtin_data)
- device_load_image(device,
- scene,
- type,
- slot,
- progress);
- }
+ ImageDataType type;
+ int slot = flattened_slot_to_type_index(flat_slot, &type);
+
+ Image *image = images[type][slot];
+ assert(image != NULL);
+
+ if (image->users == 0) {
+ device_free_image(device, type, slot);
+ }
+ else if (image->need_load) {
+ if (!osl_texture_system || image->builtin_data)
+ device_load_image(device, scene, type, slot, progress);
+ }
}
-void ImageManager::device_load_builtin(Device *device,
- Scene *scene,
- Progress& progress)
+void ImageManager::device_load_builtin(Device *device, Scene *scene, Progress &progress)
{
- /* Load only builtin images, Blender needs this to load evaluated
- * scene data from depsgraph before it is freed. */
- if(!need_update) {
- return;
- }
-
- TaskPool pool;
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- if(!images[type][slot])
- continue;
-
- if(images[type][slot]->need_load) {
- if(images[type][slot]->builtin_data) {
- pool.push(function_bind(&ImageManager::device_load_image,
- this,
- device,
- scene,
- (ImageDataType)type,
- slot,
- &progress));
- }
- }
- }
- }
-
- pool.wait_work();
+ /* Load only builtin images, Blender needs this to load evaluated
+ * scene data from depsgraph before it is freed. */
+ if (!need_update) {
+ return;
+ }
+
+ TaskPool pool;
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++) {
+ if (!images[type][slot])
+ continue;
+
+ if (images[type][slot]->need_load) {
+ if (images[type][slot]->builtin_data) {
+ pool.push(function_bind(&ImageManager::device_load_image,
+ this,
+ device,
+ scene,
+ (ImageDataType)type,
+ slot,
+ &progress));
+ }
+ }
+ }
+ }
+
+ pool.wait_work();
}
void ImageManager::device_free_builtin(Device *device)
{
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- if(images[type][slot] && images[type][slot]->builtin_data)
- device_free_image(device, (ImageDataType)type, slot);
- }
- }
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++) {
+ if (images[type][slot] && images[type][slot]->builtin_data)
+ device_free_image(device, (ImageDataType)type, slot);
+ }
+ }
}
void ImageManager::device_free(Device *device)
{
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- device_free_image(device, (ImageDataType)type, slot);
- }
- images[type].clear();
- }
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for (size_t slot = 0; slot < images[type].size(); slot++) {
+ device_free_image(device, (ImageDataType)type, slot);
+ }
+ images[type].clear();
+ }
}
void ImageManager::collect_statistics(RenderStats *stats)
{
- for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
- foreach(const Image *image, images[type]) {
- stats->image.textures.add_entry(
- NamedSizeEntry(path_filename(image->filename),
- image->mem->memory_size()));
- }
- }
+ for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ foreach (const Image *image, images[type]) {
+ stats->image.textures.add_entry(
+ NamedSizeEntry(path_filename(image->filename), image->mem->memory_size()));
+ }
+ }
}
CCL_NAMESPACE_END