diff options
Diffstat (limited to 'intern/cycles/render/image.cpp')
-rw-r--r-- | intern/cycles/render/image.cpp | 151 |
1 files changed, 122 insertions, 29 deletions
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 076cc3d8b63..7bceb8a8bfa 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -11,7 +11,7 @@ * 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 + * limitations under the License. */ #include "device.h" @@ -151,15 +151,27 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data, bo return is_float; } -static bool image_equals(ImageManager::Image *image, const string& filename, void *builtin_data, InterpolationType interpolation) +static bool image_equals(ImageManager::Image *image, + const string& filename, + void *builtin_data, + InterpolationType interpolation, + ExtensionType extension) { return image->filename == filename && image->builtin_data == builtin_data && - image->interpolation == interpolation; + image->interpolation == interpolation && + image->extension == extension; } -int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, float frame, - bool& is_float, bool& is_linear, InterpolationType interpolation, bool use_alpha) +int ImageManager::add_image(const string& filename, + void *builtin_data, + bool animated, + float frame, + bool& is_float, + bool& is_linear, + InterpolationType interpolation, + ExtensionType extension, + bool use_alpha) { Image *img; size_t slot; @@ -171,11 +183,20 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani /* find existing image */ for(slot = 0; slot < float_images.size(); slot++) { img = float_images[slot]; - if(img && image_equals(img, filename, builtin_data, interpolation)) { + if(img && image_equals(img, + filename, + builtin_data, + interpolation, + extension)) + { 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; + } img->users++; return slot; } @@ -206,6 +227,7 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani img->animated = animated; img->frame = frame; img->interpolation = interpolation; + img->extension = extension; img->users = 1; img->use_alpha = use_alpha; @@ -214,11 +236,20 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani else { for(slot = 0; slot < images.size(); slot++) { img = images[slot]; - if(img && image_equals(img, filename, builtin_data, interpolation)) { + if(img && image_equals(img, + filename, + builtin_data, + interpolation, + extension)) + { 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; + } img->users++; return slot+tex_image_byte_start; } @@ -249,6 +280,7 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani img->animated = animated; img->frame = frame; img->interpolation = interpolation; + img->extension = extension; img->users = 1; img->use_alpha = use_alpha; @@ -292,12 +324,20 @@ void ImageManager::remove_image(int slot) } } -void ImageManager::remove_image(const string& filename, void *builtin_data, InterpolationType interpolation) +void ImageManager::remove_image(const string& filename, + void *builtin_data, + InterpolationType interpolation, + ExtensionType extension) { size_t slot; for(slot = 0; slot < images.size(); slot++) { - if(images[slot] && image_equals(images[slot], filename, builtin_data, interpolation)) { + if(images[slot] && image_equals(images[slot], + filename, + builtin_data, + interpolation, + extension)) + { remove_image(slot+tex_image_byte_start); break; } @@ -306,7 +346,11 @@ void ImageManager::remove_image(const string& filename, void *builtin_data, Inte if(slot == images.size()) { /* see if it's in a float texture slot */ for(slot = 0; slot < float_images.size(); slot++) { - if(float_images[slot] && image_equals(float_images[slot], filename, builtin_data, interpolation)) { + if(float_images[slot] && image_equals(float_images[slot], + filename, + builtin_data, + interpolation, + extension)) { remove_image(slot); break; } @@ -318,12 +362,19 @@ void ImageManager::remove_image(const string& filename, void *builtin_data, Inte * without bunch of arguments passing around making code readability even * more cluttered. */ -void ImageManager::tag_reload_image(const string& filename, void *builtin_data, InterpolationType interpolation) +void ImageManager::tag_reload_image(const string& filename, + void *builtin_data, + InterpolationType interpolation, + ExtensionType extension) { size_t slot; for(slot = 0; slot < images.size(); slot++) { - if(images[slot] && image_equals(images[slot], filename, builtin_data, interpolation)) { + if(images[slot] && image_equals(images[slot], + filename, + builtin_data, + interpolation, + extension)) { images[slot]->need_load = true; break; } @@ -332,7 +383,11 @@ void ImageManager::tag_reload_image(const string& filename, void *builtin_data, if(slot == images.size()) { /* see if it's in a float texture slot */ for(slot = 0; slot < float_images.size(); slot++) { - if(float_images[slot] && image_equals(float_images[slot], filename, builtin_data, interpolation)) { + if(float_images[slot] && image_equals(float_images[slot], + filename, + builtin_data, + interpolation, + extension)) { float_images[slot]->need_load = true; break; } @@ -399,7 +454,7 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img) int scanlinesize = width*components*sizeof(uchar); in->read_image(TypeDesc::UINT8, - (uchar*)pixels + (height-1)*scanlinesize, + (uchar*)pixels + (((size_t)height)-1)*scanlinesize, AutoStride, -scanlinesize, AutoStride); @@ -417,9 +472,10 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img) builtin_image_pixels_cb(img->filename, img->builtin_data, pixels); } + size_t num_pixels = ((size_t)width) * height * depth; if(cmyk) { /* CMYK */ - for(int i = width*height*depth-1; i >= 0; i--) { + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255; pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255; pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255; @@ -428,7 +484,7 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img) } else if(components == 2) { /* grayscale + alpha */ - for(int i = width*height*depth-1; i >= 0; i--) { + 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]; @@ -437,7 +493,7 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img) } else if(components == 3) { /* RGB */ - for(int i = width*height*depth-1; i >= 0; i--) { + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { pixels[i*4+3] = 255; pixels[i*4+2] = pixels[i*3+2]; pixels[i*4+1] = pixels[i*3+1]; @@ -446,7 +502,7 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img) } else if(components == 1) { /* grayscale */ - for(int i = width*height*depth-1; i >= 0; i--) { + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { pixels[i*4+3] = 255; pixels[i*4+2] = pixels[i]; pixels[i*4+1] = pixels[i]; @@ -455,7 +511,7 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img) } if(img->use_alpha == false) { - for(int i = width*height*depth-1; i >= 0; i--) { + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { pixels[i*4+3] = 255; } } @@ -521,7 +577,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_ vector<float> tmppixels; if(components > 4) { - tmppixels.resize(width*height*components); + tmppixels.resize(((size_t)width)*height*components); readpixels = &tmppixels[0]; } @@ -539,7 +595,8 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_ } if(components > 4) { - for(int i = width*height-1; i >= 0; i--) { + 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]; @@ -558,9 +615,10 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_ builtin_image_float_pixels_cb(img->filename, img->builtin_data, pixels); } + size_t num_pixels = ((size_t)width) * height * depth; if(cmyk) { /* CMYK */ - for(int i = width*height*depth-1; i >= 0; i--) { + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { pixels[i*4+3] = 255; pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255; pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255; @@ -569,7 +627,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_ } else if(components == 2) { /* grayscale + alpha */ - for(int i = width*height*depth-1; i >= 0; i--) { + 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]; @@ -578,7 +636,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_ } else if(components == 3) { /* RGB */ - for(int i = width*height*depth-1; i >= 0; i--) { + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { pixels[i*4+3] = 1.0f; pixels[i*4+2] = pixels[i*3+2]; pixels[i*4+1] = pixels[i*3+1]; @@ -587,7 +645,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_ } else if(components == 1) { /* grayscale */ - for(int i = width*height*depth-1; i >= 0; i--) { + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { pixels[i*4+3] = 1.0f; pixels[i*4+2] = pixels[i]; pixels[i*4+1] = pixels[i]; @@ -596,7 +654,7 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_ } if(img->use_alpha == false) { - for(int i = width*height*depth-1; i >= 0; i--) { + for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { pixels[i*4+3] = 1.0f; } } @@ -653,7 +711,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl if(!pack_images) { thread_scoped_lock device_lock(device_mutex); - device->tex_alloc(name.c_str(), tex_img, img->interpolation, true); + device->tex_alloc(name.c_str(), + tex_img, + img->interpolation, + img->extension); } } else { @@ -685,7 +746,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl if(!pack_images) { thread_scoped_lock device_lock(device_mutex); - device->tex_alloc(name.c_str(), tex_img, img->interpolation, true); + device->tex_alloc(name.c_str(), + tex_img, + img->interpolation, + img->extension); } } @@ -783,7 +847,36 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress& need_update = false; } -void ImageManager::device_pack_images(Device *device, DeviceScene *dscene, Progress& progess) +void ImageManager::device_update_slot(Device *device, + DeviceScene *dscene, + int slot, + Progress *progress) +{ + Image *image; + if(slot >= tex_image_byte_start) { + int byte_slot = slot - tex_image_byte_start; + assert(images[byte_slot] != NULL); + image = images[byte_slot]; + } + else { + assert(float_images[slot] != NULL); + image = float_images[slot]; + } + if(image->users == 0) { + device_free_image(device, dscene, slot); + } + else if(image->need_load) { + if(!osl_texture_system || float_images[slot]->builtin_data) + device_load_image(device, + dscene, + slot, + progress); + } +} + +void ImageManager::device_pack_images(Device *device, + DeviceScene *dscene, + Progress& /*progess*/) { /* for OpenCL, we pack all image textures inside a single big texture, and * will do our own interpolation in the kernel */ |