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/image.cpp')
-rw-r--r--intern/cycles/render/image.cpp108
1 files changed, 89 insertions, 19 deletions
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 7465fbd43a7..11193bf4974 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -19,6 +19,7 @@
#include "scene.h"
#include "util_foreach.h"
+#include "util_logging.h"
#include "util_path.h"
#include "util_progress.h"
#include "util_texture.h"
@@ -476,6 +477,7 @@ template<TypeDesc::BASETYPE FileFormat,
typename DeviceType>
bool ImageManager::file_load_image(Image *img,
ImageDataType type,
+ int texture_limit,
device_vector<DeviceType>& tex_img)
{
const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1;
@@ -485,9 +487,15 @@ bool ImageManager::file_load_image(Image *img,
return false;
}
/* Read RGBA pixels. */
- StorageType *pixels = (StorageType*)tex_img.resize(width, height, depth);
- if(pixels == NULL) {
- return false;
+ vector<StorageType> pixels_storage;
+ StorageType *pixels;
+ const size_t max_size = max(max(width, height), depth);
+ if(texture_limit > 0 && max_size > texture_limit) {
+ pixels_storage.resize(((size_t)width)*height*depth*4);
+ pixels = &pixels_storage[0];
+ }
+ else {
+ pixels = (StorageType*)tex_img.resize(width, height, depth);
}
bool cmyk = false;
if(in) {
@@ -526,12 +534,12 @@ bool ImageManager::file_load_image(Image *img,
if(FileFormat == TypeDesc::FLOAT) {
builtin_image_float_pixels_cb(img->filename,
img->builtin_data,
- (float*)pixels);
+ (float*)&pixels[0]);
}
else if(FileFormat == TypeDesc::UINT8) {
builtin_image_pixels_cb(img->filename,
img->builtin_data,
- (uchar*)pixels);
+ (uchar*)&pixels[0]);
}
else {
/* TODO(dingto): Support half for ImBuf. */
@@ -540,10 +548,10 @@ bool ImageManager::file_load_image(Image *img,
/* Check if we actually have a float4 slot, in case components == 1,
* but device doesn't support single channel textures.
*/
- if(type == IMAGE_DATA_TYPE_FLOAT4 ||
- type == IMAGE_DATA_TYPE_HALF4 ||
- type == IMAGE_DATA_TYPE_BYTE4)
- {
+ bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 ||
+ type == IMAGE_DATA_TYPE_HALF4 ||
+ type == IMAGE_DATA_TYPE_BYTE4);
+ if(is_rgba) {
size_t num_pixels = ((size_t)width) * height * depth;
if(cmyk) {
/* CMYK */
@@ -587,14 +595,41 @@ bool ImageManager::file_load_image(Image *img,
}
}
}
+ 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 = (StorageType*)tex_img.resize(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, DeviceScene *dscene, ImageDataType type, int slot, Progress *progress)
+void ImageManager::device_load_image(Device *device,
+ DeviceScene *dscene,
+ 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)
@@ -603,6 +638,8 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
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);
@@ -622,7 +659,11 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
device->tex_free(tex_img);
}
- if(!file_load_image<TypeDesc::FLOAT, float>(img, type, tex_img)) {
+ if(!file_load_image<TypeDesc::FLOAT, float>(img,
+ type,
+ texture_limit,
+ tex_img))
+ {
/* on failure to load, we set a 1x1 pixels pink image */
float *pixels = (float*)tex_img.resize(1, 1);
@@ -648,7 +689,11 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
device->tex_free(tex_img);
}
- if(!file_load_image<TypeDesc::FLOAT, float>(img, type, tex_img)) {
+ if(!file_load_image<TypeDesc::FLOAT, float>(img,
+ type,
+ texture_limit,
+ tex_img))
+ {
/* on failure to load, we set a 1x1 pixels pink image */
float *pixels = (float*)tex_img.resize(1, 1);
@@ -671,7 +716,11 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
device->tex_free(tex_img);
}
- if(!file_load_image<TypeDesc::UINT8, uchar>(img, type, tex_img)) {
+ if(!file_load_image<TypeDesc::UINT8, uchar>(img,
+ type,
+ texture_limit,
+ tex_img))
+ {
/* on failure to load, we set a 1x1 pixels pink image */
uchar *pixels = (uchar*)tex_img.resize(1, 1);
@@ -697,7 +746,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
device->tex_free(tex_img);
}
- if(!file_load_image<TypeDesc::UINT8, uchar>(img, type, tex_img)) {
+ if(!file_load_image<TypeDesc::UINT8, uchar>(img,
+ type,
+ texture_limit,
+ tex_img)) {
/* on failure to load, we set a 1x1 pixels pink image */
uchar *pixels = (uchar*)tex_img.resize(1, 1);
@@ -720,7 +772,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
device->tex_free(tex_img);
}
- if(!file_load_image<TypeDesc::HALF, half>(img, type, tex_img)) {
+ if(!file_load_image<TypeDesc::HALF, half>(img,
+ type,
+ texture_limit,
+ tex_img)) {
/* on failure to load, we set a 1x1 pixels pink image */
half *pixels = (half*)tex_img.resize(1, 1);
@@ -746,7 +801,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
device->tex_free(tex_img);
}
- if(!file_load_image<TypeDesc::HALF, half>(img, type, tex_img)) {
+ if(!file_load_image<TypeDesc::HALF, half>(img,
+ type,
+ texture_limit,
+ tex_img)) {
/* on failure to load, we set a 1x1 pixels pink image */
half *pixels = (half*)tex_img.resize(1, 1);
@@ -842,7 +900,10 @@ void ImageManager::device_free_image(Device *device, DeviceScene *dscene, ImageD
}
}
-void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress& progress)
+void ImageManager::device_update(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress& progress)
{
if(!need_update)
return;
@@ -859,7 +920,14 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress&
}
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, dscene, (ImageDataType)type, slot, &progress));
+ pool.push(function_bind(&ImageManager::device_load_image,
+ this,
+ device,
+ dscene,
+ scene,
+ (ImageDataType)type,
+ slot,
+ &progress));
}
}
}
@@ -874,6 +942,7 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress&
void ImageManager::device_update_slot(Device *device,
DeviceScene *dscene,
+ Scene *scene,
int flat_slot,
Progress *progress)
{
@@ -890,6 +959,7 @@ void ImageManager::device_update_slot(Device *device,
if(!osl_texture_system || image->builtin_data)
device_load_image(device,
dscene,
+ scene,
type,
slot,
progress);